spring-data-redis 项目,配合 spring 特性并集成 Jedis 的一些命令和方法。
配置redis继承到spring管理项目,使用注解实现redis缓存功能。
步骤:1.maven的pom.xml文件导入架包
2.配置文件添加配置
3.spring管理bean的生成,xml文件配置
4. RedisCacheConfig redis自定义的工具类,自定义redis的key生成规则
5.
1.maven的pom.xml文件导入架包【本来spring-data-redis架包版本使用最新的2.0.0 ,甚至使用到1.8.4版本,只要保存,启动项目,spring管理的bean都会创建失败,架包冲突的缘故或者其他问题,所以退而求其次,使用1.6.2版本】
<!-- redis架包 --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.6.2.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
2.配置文件添加配置
#============================# #==== Redis settings ====# #============================# #redis 服务器 IP redis.host=127.0.0.1 #redis 服务器端口 redis.port=6379 #redis 密码 redis.pass=398023 #redis 支持16个数据库(相当于不同用户)可以使不同的应用程序数据彼此分开同时又存储在相同的实例上 redis.dbIndex=0 #redis 缓存数据过期时间单位秒 redis.expiration=3000 #控制一个 pool 最多有多少个状态为 idle 的jedis实例 redis.maxIdle=300 #控制一个 pool 可分配多少个jedis实例 redis.maxActive=600 #当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException; redis.maxWait=1000 #在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的; redis.testOnBorrow=true
3.spring管理bean的生成,xml文件配置
<!-- **************************************************redis********************************************************** --> <!-- 配置 JedisPoolConfig 实例 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.maxIdle}"/> <property name="maxTotal" value="${redis.maxActive}"/> <property name="maxWaitMillis" value="${redis.maxWait}"/> <property name="testOnBorrow" value="${redis.testOnBorrow}"/> </bean> <!-- 配置JedisConnectionFactory --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="${redis.host}"/> <property name="port" value="${redis.port}"/> <property name="password" value="${redis.pass}"/> <property name="database" value="${redis.dbIndex}"/> <property name="poolConfig" ref="poolConfig"/> </bean> <!-- 配置RedisTemplate --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory"/> </bean> <!-- 配置RedisCacheManager --> <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"> <constructor-arg name="redisOperations" ref="redisTemplate"/> <property name="defaultExpiration" value="${redis.expiration}"/> </bean> <!-- 配置RedisCacheConfig --> <bean id="redisCacheConfig" class="com.sxd.util.RedisCacheConfig"> <constructor-arg ref="jedisConnectionFactory"/> <constructor-arg ref="redisTemplate"/> <constructor-arg ref="redisCacheManager"/> </bean>
JedisPoolConfig jedis连接池配置对象
JedisConnectionFactory jedis连接工厂,生成连接对象
RedisTemplate RedisTemplate 对 RedisConnection 进行了封装。提供连接管理,序列化等功能,它对 Redis 的交互进行了更高层次的抽象,极大的方便和简化了 Redis 的操作
RedisCacheManager 做为 redis 统一的调度和管理者
RedisCacheConfig RedisCacheConfig extends org.springframework.cache.annotation.CachingConfigurerSupport,自定义redis的key生成规则,如果不在注解参数中注明key=“”的话,就采用这个类中的key生成规则生成key
4. RedisCacheConfig redis自定义的工具类,自定义redis的key生成规则
package com.sxd.util; import java.lang.reflect.Method; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; @Configuration @EnableCaching public class RedisCacheConfig extends CachingConfigurerSupport { protected final static Logger log = LoggerFactory.getLogger(RedisCacheConfig.class); private volatile JedisConnectionFactory mJedisConnectionFactory; private volatile RedisTemplate<String, String> mRedisTemplate; private volatile RedisCacheManager mRedisCacheManager; public RedisCacheConfig() { super(); } public RedisCacheConfig(JedisConnectionFactory mJedisConnectionFactory, RedisTemplate<String, String> mRedisTemplate, RedisCacheManager mRedisCacheManager) { super(); this.mJedisConnectionFactory = mJedisConnectionFactory; this.mRedisTemplate = mRedisTemplate; this.mRedisCacheManager = mRedisCacheManager; } public JedisConnectionFactory redisConnectionFactory() { return mJedisConnectionFactory; } public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) { return mRedisTemplate; } public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) { return mRedisCacheManager; } @Bean public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { //规定 本类名+方法名+参数名 为key StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()+"_"); sb.append(method.getName()+"_"); for (Object obj : params) { sb.append(obj.toString()+","); } return sb.toString(); } }; } }
5.在你想要做缓存的地方,使用注解进行缓存
先介绍几个注解
1》@CacheConfig 配置在类上,cacheNames即定义了本类中所有用到缓存的地方,都去找这个库。只要使用了这个注解,在方法上@Cacheable @CachePut @CacheEvict就可以不用写value去找具体库名了
2》@Cacheable 配置在方法或类上,作用:本方法执行后,先去缓存看有没有数据,如果没有,从数据库中查找出来,给缓存中存一份,返回结果,下次本方法执行,在缓存未过期情况下,先在缓存中查找,有的话直接返回,没有的话从数据库查找
3》@CachePut 类似于更新操作,即每次不管缓存中有没有结果,都从数据库查找结果,并将结果更新到缓存,并返回结果
4》@CacheEvict 用来清除用在本方法或者类上的缓存数据(用在哪里清除哪里)
例子:
说明:
①使用了@Cacheable(value="myUser"),即表示缓存中有,直接从缓存取出,没有的话先从数据库中查出,然后再插入
②如果未在类上使用@CacheConfig注解规定数据要缓存到哪个库中,就必须给value一个值,规定数据最后缓存到哪个redis库中
③因为redis缓存数据实际就是键值对的形式存储,因此必须给定key-value的key,这里没有给key参数赋值,所以key的生成规则按照上面工具类中规定的key生成的
④key-value的value就是本方法的返回值,如果要缓存登录用户信息,本方法需要进行修改,返回user对象就可以缓存到key-value的value中
查看一下本次缓存的数据,在redis可视化工具中
①redis以键值对的形式存储缓存数据,而且会对对象进行序列化,如上图可以看到,键和值前面都有一串序列化的字符
② RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。JdkSerializationRedisSerializer
③SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。
StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。StringRedisSerializer
RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。JdkSerializationRedisSerializer
就是因为序列化策略的不同,即使是同一个key用不同的Template去序列化,结果是不同的。所以根据key去删除数据的时候就出现了删除失败的问题。
④在上面配置文件中,没有显式的给出序列化策略,会有默认的序列化策略。
⑤如果因为序列化策略不同,可以区显式的设置
<!-- redis 序列化策略 ,通常情况下key值采用String序列化策略, --> <!-- 如果不指定序列化策略,StringRedisTemplate的key和value都将采用String序列化策略; --> <!-- 但是RedisTemplate的key和value都将采用JDK序列化 这样就会出现采用不同template保存的数据不能用同一个template删除的问题 --> <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" /> <bean id=‘redisWriteTemplate‘ class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisWriteConnectionFactory" /> <property name="keySerializer" ref="stringRedisSerializer" /> <property name="hashKeySerializer" ref="stringRedisSerializer" /> </bean>
最后给出这几个注解的具体参数以及使用相关配图参考。