前言
由于Redis只能提供基于字符串型的操作,而Java中使用的却以类对象为主,所以需要Redis存储的字符串和Java对象相互转换。如果我们自己编写这些规则,工作量是比较大的,因此本文介绍如何使用Spring框架快速实现Java数据类型在Redis中的存储(序列化和反序列化操作)
在Spring中使用Redis
在Spring中使用Redis,除了需要jedis.jar外,还需要下载spring-data-redis.jar,如果使用maven项目,导入以下坐标即可:
pom.xml
<!--jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!--spring-data-redis-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
这里值得注意的是jar包和Spring版本兼容的问题,不同版本可能不兼容,从而产生异常,这就需要依靠实际开发的经验来决定了。
RedisTemplate的使用
在Spring中提供了RedisTemplate模版类,来简化我们对redis的操作。
在Spring.xml文件中配置
JedisPoolConfig对象
大部分情况下我们会用到连接器,因此先用Spring配置一个JedisPoolConfig对象,这个配置相对简单:
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="50"/> <property name="maxTotal" value="100"/> <property name="maxWaitMillis" value="20000"/> </bean>
连接工厂
在使用Spring提供的RedisTemplate之前,需要配置Spring提供的连接工厂,在Spring Data Redis方案中提供了4中工厂模型。
- JredisConnectionFactory
- JedisConnectionFactory
- LettuceConnectionFactory
- SrpConnectionFactory
虽然使用哪种实现工厂都是可以的,但是要根据环境进行测试,以验证使用哪个方案的性能最佳。无论如何它们都是接口RedisConnectionFactory的实现类,本文使用最为广泛的JedisConnectionFactory为例进行讲解。
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="localhost"/> <property name="port" value="6379"/> <property name="poolConfig" ref="poolConfig"/> </bean>
- hostName ,代表的是服务器 默认值是 localhost 所以如果是本机可以不配置它。
- port ,代表的是接口端口,默认值是 6379 ,所以可以使用默认的 Redis 端口,也可以不配置它。
- password ,代表的是密码,在需要密码连接 Redis 的场合需要配置它。
- poolConfig 是连接池配置对象 可以设置连接池的属性。
Java对象的序列化
普通的连接使用没有办法把 Java 象直接存入 Redis ,而需要我们自己提供方案,这
时往往就是将对象序列化,然后使用 Redis 进行存储,而取回序列化的内容后,在通过转
换转变为 Java 对象, Spring 模板中提供了封装的方案,在它内部提供了 RedisSerializer
口( org.spring amework.data.redis.serializer.RedisSerializer )和一些实现类。
原理图
配置Spring RedisTemplate
<bean id="jdkSeria" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/> <bean id="stringSeria" class="org.springframework.data.redis.serializer.StringRedisSerializer"/> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="connectionFactory"/> <property name="keySerializer" ref="stringSeria"/> <property name="valueSerializer" ref="jdkSeria"/> </bean>
- 配置jdk序列化器,将java对象转化为redis的值(value)
- 配置string序列化起,将java的字符串转化为redis的键(key)
完整的Spring.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="50"/>
<property name="maxTotal" value="100"/>
<property name="maxWaitMillis" value="20000"/>
</bean>
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="localhost"/>
<property name="port" value="6379"/>
<property name="poolConfig" ref="poolConfig"/>
</bean>
<bean id="jdkSeria" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
<bean id="stringSeria" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="keySerializer" ref="stringSeria"/>
<property name="valueSerializer" ref="jdkSeria"/>
</bean>
</beans>
测试
@Test
public void SeriaTest(){
ApplicationContext context =new ClassPathXmlApplicationContext("spring.xml");
RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);
User user =new User();
user.setName("小王");
user.setCity("上海");
user.setAge(18);
redisTemplate.opsForValue().set("user_1",user);
}
@Test
public void getSeriaTest(){
ApplicationContext context =new ClassPathXmlApplicationContext("spring.xml");
RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);
User u = (User)redisTemplate.opsForValue().get("user_1");
System.out.println(u);
}
序列化和反序列化操作
序列化
序列化和反序列化的前提,是我们的实体类实现了序列化接口:
打开redis的命令行工具
输入keys * 指令查看所有键
查看键的值
已经完成了序列化操作
反序列化
可以获取到数据,反序列化成功