Spring之Redis访问(Spring-data-redis)详解数据库
Spring-data-redis,是spring-data框架中,比较常用的,基于key-value键值对的数据持久层框架。Spring-data-redis,是一个基于Template模板开发的数据访问层框架。都是基于配置+template方法调用,实现redis数据CRUD操作的。
没有Spring-data-redis的时候,使用jedis-client来实现redis的访问。需要自己控制jedis中的具体逻辑,实现redis数据的CURD操作。
spring-data框架中的每个子模块其版本未必一致,毕竟对应不同数据服务的访问层框架,更新时间和周期是不同的。在本案例中,使用的spring-data-redis版本为1.8.14。spring-data-redis框架的执行需要jackson组件的辅助,建议导入jackson版本为2.7+(对应当前环境中的spring-data-redis版本)。
包依赖:
!-- spring-data-redis核心 -- dependency groupId org.springframework.data /groupId artifactId spring-data-redis /artifactId version 1.8.14.RELEASE /version /dependency !-- redis-client核心 -- dependency groupId redis.clients /groupId artifactId jedis /artifactId version 2.9.0 /version /dependency !-- spring-data-redis做数据转换使用的辅助插件 -- dependency groupId com.fasterxml.jackson.core /groupId artifactId jackson-databind /artifactId version 2.9.5 /version /dependency
全局配置applicationContext.xml:
?xml version="1.0" encoding="UTF-8"? beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd" !-- 配置读取properties文件的工具类 -- context:property-placeholder location="classpath:redis/redis.properties"/ !-- Jedis连接池,高效连接 value配置来自文件redis.properties-- bean id="poolConfig" property name="maxTotal" value="${redis.pool.maxTotal}"/ property name="maxIdle" value="${redis.pool.maxIdle}"/ property name="minIdle" value="${redis.pool.minIdle}"/ /bean !-- redis集群配置 -- bean id="redisClusterConfig" constructor-arg name="clusterNodes" list value 192.168.2.124:7001 /value value 192.168.2.124:7002 /value value 192.168.2.124:7003 /value value 192.168.2.124:7004 /value value 192.168.2.124:7005 /value value 192.168.2.124:7006 /value /list /constructor-arg /bean !-- Jedis的连接工厂,不可缺少的。是用于构建连接对象jedis的。 -- bean id="jedisConnectionFactory" !-- 单机版访问配置 -- property name="hostName" value="${redis.conn.hostName}"/ property name="port" value="${redis.conn.port}"/ property name="poolConfig" ref="poolConfig"/ !-- 集群版访问配置 -- !-- constructor-arg name="clusterConfig" ref="redisClusterConfig" / constructor-arg name="poolConfig" ref="poolConfig" / -- /bean !-- Redis模板对象,类似JDBCTemplate。模板方法模式开发的代码。RedisTemplate中定义了若干的方法,用于实现数据的CRUD操作。 -- bean id="redisTemplate" property name="connectionFactory" ref="jedisConnectionFactory"/ !-- 序列化器:能够把我们储存的key与value做序列化处理的对象,是一个类似于converter的工具。 可以实现传入的java对象- redis可以识别的数据类型。 如:字符串。 默认的Serializer是StringRedisSerializer。 设定默认的序列化器是字符串序列化器,原因是redis可以存储的数据只有字符串和字节数组。 一般来说,我们代码中操作的数据对象都是java对象。 如果代码中,使用的数据载体就是字符串对象,那么使用Jackson2JsonRedisSerializer来做序列化器是否会有问题? 如果jackson插件的版本不合适,有错误隐患的话,可能将字符串数据转换为json字符串 - {chars:[], bytes:[]} 使用StringRedisSerializer就没有这个问题。不处理字符串转换的。认为代码中操作的key和value都是字符串。 !-- 配置默认的序列化器 -- !-- keySerializer、valueSerializer 配置Redis中的String类型key与value的序列化器 -- !-- HashKeySerializer、HashValueSerializer 配置Redis中的Hash类型key与value的序列化器 -- property name="keySerializer" bean / /property property name="valueSerializer" bean / /property /bean /beans
Redis数据库连接配置:redis.properties
redis.pool.maxTotal=20 redis.pool.maxIdle=10 redis.pool.minIdle=5 redis.conn.hostName=127.0.0.1 redis.conn.port=6379
测试类:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:redis/applicationContext.xml") public class RedisTest { @Autowired private RedisTemplate String, Object redisTemplate; /** * 添加键值对 - 字符串类型 * redisTemplate中,提供了若干的Operations,每一个Operations对应一个Redis中的数据类型。 * 如:ValueOperations - 字符串类型。 HashOperations - hash类型。 @Test public void test1(){ ValueOperations String, Object ops = this.redisTemplate.opsForValue(); ops.set("key", "test"); /** * 获取redis中的数据 @Test public void test2(){ String str = (String)this.redisTemplate.opsForValue().get("key"); System.out.println(str); // 新增/更新数据,并设置有效期。 // this.redisTemplate.opsForValue().set("key", "test", 10L, TimeUnit.SECONDS); // 设置数据有效期。 this.redisTemplate.expire("key", 10, TimeUnit.SECONDS); /** * 添加Users * 将java对象,存储到redis中,可以使用两种存储方式。 * 1 - 使用JDK提供的Serializable,实现对象序列化。 * 改变valueSerilizer的序列化器。JdkSerializationRedisSerializer * 用JDKSerializationRedisSerializer做序列化,有不好的地方。 * JDKSerialization序列化结果太长。占用更多的字节空间。进行序列化和反序列化的效率较低。 * 并且对象必须实现序列化接口,如public class Users implements Serializable @Test public void test3(){ Users users = new Users(); users.setUserage(30); users.setUserid(1); users.setUsername("张三"); //更换序列化器,通过API来更换序列化器,好处是有针对性。需要什么序列化器就提供什么序列化器。默认都使用StringRedisSerializer this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); this.redisTemplate.opsForValue().set("users", users); /** * 获取Users @Test public void test4(){ //更换序列化器 this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); Users users = (Users)this.redisTemplate.opsForValue().get("users"); System.out.println(users); /** * 添加Users JSON格式 * JSON数据,人机皆可使用。 * JSON数据占用的存储空间小,且和java对象的转换效率高。 * 缺陷 - 不能描述双向关系。如果使用json来描述双向关联关系,则会出现无限嵌套,是一个死循环。会有内存溢出错误, OutOfMemeryError * class A{ B b; } * class B{ A a; } * A a = new A(); * json - { .... , b : { ... , a : { ...., b : { ...., a : { }}}}} @Test public void test5(){ Users users = new Users(); users.setUserage(30); users.setUserid(2); users.setUsername("李四"); this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer Users (Users.class)); this.redisTemplate.opsForValue().set("usersjson", users); /** * 获取Uesrs JSON格式 @Test public void test6(){ this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer Users (Users.class)); Users users = (Users)this.redisTemplate.opsForValue().get("usersjson"); System.out.println(users); /** * 常用API @Test public void test7(){ // 设置有效期 this.redisTemplate.expire("usersjson", 300, TimeUnit.SECONDS); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); // 查询有效期 long expire = this.redisTemplate.getExpire("usersjson"); System.out.println("expire = " + expire); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); // 删除有效期 this.redisTemplate.persist("usersjson"); }
User实体类:
@Entitypublic class Users implements Serializable{ private Integer userid;private String username;private Integer userage;
public Users(String username, Integer userage){ this.username = username; this.userage = userage; public Integer getUserid() { return userid; public void setUserid(Integer userid) { this.userid = userid; public String getUsername() { return username; public void setUsername(String username) { this.username = username; public Integer getUserage() { return userage; public void setUserage(Integer userage) { this.userage = userage; @Override public String toString() { return "Users [userid=" + userid + ", username=" + username + ", userage=" + userage + "]"; }
知识补充(序列化:Serialize)
功能 将内存中的java对象与字节数组做双向转换。
作用 只要涉及到IO操作的时候,IO中可以传递的数据只有字节,java对象是不能通过IO传递的。所以,需要使用IO传递java对象的时候,必须涉及到序列化和反序列化。
序列化ID 是用于区分字节信息和java类型直接关系的一个基础数据。如果设计上,不怕麻烦,建议给不同的类型,定义尽可能不同的序列化ID,可以提升序列化和反序列化的效率。但是,对效率的提升不是很明显。
序列化ID,只有一个要求,就是一样的类型的对象,必须使用相同值的序列化ID。
一般开发的时候,序列化ID都设置为-1/1。
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/3804.html
Redis相关文章
- Redis强力驱动:建立高效数据库(redis建库)
- 优雅的构建:基于Redis的数据库设计(redis设计数据库)
- 使用Redis:理解默认数据库(redis默认数据库)
- Redis简易指南:快速建立一个数据库(redis建立数据库)
- 如何有效利用 Redis 数据库(怎样用redis数据库)
- 使用微擎搭配Redis优化系统配置(微擎 redis 配置)
- 快速获取Redis数据库的时间戳(获取redis 的时间戳)
- 如何有效的查询Redis分布式锁(查询redis锁)
- 查看Redis存放目录一步步教你如何快速定位(查看redis存放目录)
- 深入了解查看Redis中的数据库(查看redis中的数据库)
- 极速传递数据库之间Redis发送通知(数据库通知redis)
- 通过Shell脚本管理Redis数据库(shell打开redis)
- 卸载Redis关闭数据库连接(卸载redis关闭)
- 如何查询Redis数据库技术指南(如何查询redis数据库)
- 利用Redis实现数据存储的简单而有效的方式(使用了redis数据库)
- Redis查询的高频应用(redis频繁查询)
- 题Redis雪崩与穿透面试制胜的关键因素(redis雪崩和穿透面试)
- Redis集群的性能指标评估(redis集群性能指标)
- 解决Redis重启导致的数据过期问题(redis重启数据过期)
- 行Redis数据库命令行入口进入Redis的db之门(redis 进入db命令)