集成方式
先直接上代码,spring-redis配置如下:
<?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:p="http://www.springframework.org/schema/p"
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="${redis.maxIdle}"/>
<property name="maxTotal" value="${redis.maxTotal}"/>
<property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
<property name="testOnBorrow" value="${redis.testOnBorrow}"/>
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:hostName="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:poolConfig-ref="poolConfig"/>
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
</bean>
</beans>
测试demo如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:config/spring/spring-web.xml", "classpath:config/spring/spring-redis.xml","classpath:config/spring/springMVC.xml",
"classpath:config/spring/spring-dal.xml"})
public class StringRedisTempTest {
@Resource
private StringRedisTemplate stringRedisTemplate;
@Test
public void boundHashOpts(){
String key = "settings";
System.out.println("==============Hash==============");
BoundHashOperations<String, String, String> ops = stringRedisTemplate.boundHashOps(key);
ops.put("stu01","123");
String key1 = ops.getKey();
System.out.println("key1:"+key1);
String key11 = ops.get("stu01");
System.out.println("key11:"+key11);
ops.putIfAbsent("stu02","456");
String key2 = ops.getKey();
System.out.println("key2:"+key2);
String key21 = ops.get("stu02");
System.out.println("key21:"+key21);
//获取所有的key-value
Map<String,String> maps = ops.entries();
Iterator ite = maps.entrySet().iterator();
while (ite.hasNext()){
Map.Entry<String,String> entryMap = (Map.Entry<String, String>) ite.next();
System.out.println("key:"+entryMap.getKey());
System.out.println("value:"+entryMap.getValue());
}
}
}
Redis服务器启动起来之后就可以直接运行。
操作模板
通过代码可以直观地看到,redis集成到spring中是很简单的。Spring中使用的redis是spring框架自己封装的redis,叫做spring-data-redis,简称SDR,使用的时候当然要引入相应的jar包。与Java提供的jedis相比,spring-data-redis提供了更多的好处:对具体redis客户端做了封装,客户端可在jedis,jredis,rjc等Java客户端中做出选择和切换;用template对调用做了封装,省去了建立连接,释放连接等繁琐代码;对对象的序列化也可自由选择工具;提供了对spring cache的支持,可用注解实现Cache(但是无法设定缓存失效时间)。
在上文的代码中可以看到,就是使用了stringRedisTemplate模板类来对redis进行操作。StringRedisTemplate主要提供对String类型的封装操作,具体的API这里就不说了。如果要存储Java对象就不能使用String的操作模板了,可以使用RedisTemplate,该操作模板提供了对Java对象的操作的封装。使用两种操作模板的时候有一个问题需要注意,用A操作模板保存的数据只能用A操作模板进行删除,而不能用B操作模板删除。原因是两种模板的序列化策略是不同的。SDR默认采用的序列化策略有两种。分别是String的序列化策略和JDK的序列化策略。StringRedisTemplate默认采用String的序列化策略,保存的key和value都是采用此策略进行保存的。而Redis默认采用的是JDK的序列化策略。因此同一个key用不同的Template序列化的结果是不同的,所以不同的操作模板不能操作对方序列化的数据。解决这一问题也很简单,前面说过,SDR对对象的序列化可以自由选择工具,因此只要指定两种操作模板的序列化策略一致即可。具体做法是:手动指定RedisTemplate的序列化策略:
<bean id="stringRedisSerializer"
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<bean id='redisTemplate' class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<property name="keySerializer" ref="stringRedisSerializer" />
<property name="hashKeySerializer" ref="stringRedisSerializer" />
</bean>
除了上述两种序列化方式之外,SDR还提供其他序列化策略:JacksonJsonRedisSerializer / Jackson2JsonRedisSerializer/OxmSerializer等。
API
SDR对redis的存取操作进行了分类封装,将统一类型的操作封装为operation接口:
ValueOperations:简单的K-V操作。
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperation:针对map类型的数据操作
ListOperations:针对list类型的数据操作
对应的还有绑定化key的便捷化操作API,可以通过bound封装指定的key,然后进行一系列的操作而无须再次显示指定key,即BoundKeyOperations:
BoundValueOperations
BoundSetOperations
BoundListOperations
BoundSetOperations
BoundHashOperations
举个简单例子:
HashOperations<String,String,String> hashOperations = stringRedisTemplate.opsForHash();
String copyKey11 = hashOperations.get("settings","stu01");
System.out.println("等价于绑定哈希操作中的get(stu01):"+copyKey11);
参考文章:
[1] http://www.open-open.com/lib/view/open1427335294168.html
[2] http://blog.youkuaiyun.com/fengzheku/article/details/49735785