首先在开始的时候,我们应该注意到springboot的版本,在springboot1.x版本是默认使用的jedis作为连接redis的驱动,在springboot2.x及以上的版本默认使用的是Lettuce作为redis的连接池,那么这两个有什么区别呢?
jedis在实现上是直接连接redis server的,在多线程的情况下,并非是线程安全的,当然我们可以在应用层面来保证线程安全,但是我们希望我们在做业务的时候,不需要关系太多其他插件的细节。在这种情况下Lettuce就出现了,Lettuce的连接是基于Netty的,可以在多个线程间并发访问,并且Lettuce是线程安全的。 本次介绍我们将会依次使用jedis和Lettuce,可以根据自己的需求进行选择。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
// @Bean
// public RedisConnectionFactory factory(){
// JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
// // host
// jedisConnectionFactory.setHostName("");
// // 端口
// jedisConnectionFactory.setPort(6379);
// // 密码
// jedisConnectionFactory.setPassword("");
// // 连接超时时间
// jedisConnectionFactory.setTimeout(2000);
// // 默认连接数量配置
// JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// jedisPoolConfig.setMaxIdle(8);
// jedisPoolConfig.setMinIdle(0);
// jedisPoolConfig.setMaxTotal(8);
// jedisConnectionFactory.setPoolConfig(jedisPoolConfig);
// return jedisConnectionFactory;
// }
/**
* redistemplate相关配置
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, ?> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, ?> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(factory);
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSeial.setObjectMapper(om);
// 值采用json序列化
template.setValueSerializer(jacksonSeial);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 设置hash key 和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jacksonSeial);
// 初始化配置
template.afterPropertiesSet();
return template;
}
/**
* 对hash类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public HashOperations<String, String, ?> hashOperations(RedisTemplate<String, ?> redisTemplate) {
return redisTemplate.opsForHash();
}
/**
* 对redis字符串类型数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public ValueOperations<?, ?> valueOperations(RedisTemplate<?, ?> redisTemplate) {
return redisTemplate.opsForValue();
}
/**
* 对链表类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public ListOperations<?, ?> listOperations(RedisTemplate<?, ?> redisTemplate) {
return redisTemplate.opsForList();
}
/**
* 对无序集合类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public SetOperations<?, ?> setOperations(RedisTemplate<?, ?> redisTemplate) {
return redisTemplate.opsForSet();
}
/**
* 对有序集合类型的数据操作
*
* @param redisTemplate
* @return
*/
@Bean
public ZSetOperations<?, ?> zSetOperations(RedisTemplate<?, ?> redisTemplate) {
return redisTemplate.opsForZSet();
}
jedis的连接配置我们可以通过代码配置,也可以通过配置文件配置,一般的我们会通过配置文件进行配置,这样在多环境切换的时候更加的灵活,以下是配置文件的内容
spring:
redis:
host: localhost
password: 123
port: 6379
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 0
如果没有pssword参数,可以直接删除
@Service
public class RedisService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
/**
* 默认过期时长,单位:秒
*/
public static final long DEFAULT_EXPIRE = 60 * 60 * 24;
/**
* 不设置过期时长
*/
public static final long NOT_EXPIRE = -1;
public boolean existsKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* 重名名key,如果newKey已经存在,则newKey的原值被覆盖
*
* @param oldKey
* @param newKey
*/
public void renameKey(String oldKey, String newKey) {
redisTemplate.rename(oldKey, newKey);
}
/**
* newKey不存在时才重命名
*
* @param oldKey
* @param newKey
* @return 修改成功返回true
*/
public boolean renameKeyNotExist(String oldKey, String newKey) {
return redisTemplate.renameIfAbsent(oldKey, newKey);
}
/**
* 删除key
*
* @param key
*/
public void deleteKey(String key) {
redisTemplate.delete(key);
}
/**
* 删除多个key
*
* @param keys
*/
public void deleteKey(String... keys) {
Set<String> kSet = Stream.of(keys).map(k -> k).collect(Collectors.toSet());
redisTemplate.delete(kSet);
}
/**
* 删除Key的集合
*
* @param keys
*/
public void deleteKey(Collection<String> keys) {
Set<String> kSet = keys.stream().map(k -> k).collect(Collectors.toSet());
redisTemplate.delete(kSet);
}
/**
* 设置key的生命周期
*
* @param key
* @param time
* @param timeUnit
*/
public void expireKey(String key, long time, TimeUnit timeUnit) {
redisTemplate.expire(key, time, timeUnit);
}
/**
* 指定key在指定的日期过期
*
* @param key
* @param date
*/
public void expireKeyAt(String key, Date date) {
redisTemplate.expireAt(key, date);
}
/**
* 查询key的生命周期
*
* @param key
* @param timeUnit
* @return
*/
public long getKeyExpire(String key, TimeUnit timeUnit) {
return redisTemplate.getExpire(key, timeUnit);
}
/**
* 将key设置为永久有效
*
* @param key
*/
public void persistKey(String key) {
redisTemplate.persist(key);
}
}
该配置是一些一般的缓存策略的封装,包括查询key的存在,或者设置缓存的过期时间等
// 加入依赖, 以普通字符串类型的缓存作演示
@Autowired
private ValueOperations<String,Object> valueOperations;
// 加入缓存策略
@Autowired
private RedisService redisService;
public void setRedisMessage(){
try{
// 将数据缓存,可以直接存储自定义对象,我们在配置conifg的时候已经指定了序列化工具
valueOperations.set(key,Object);
// 设置这个key对应的缓存的过期时间,此处设置为60s过期
redisService.expireKey(key,60, TimeUnit.SECONDS);
}catch(RedisConnectionFailureException e){
// 使用redis可能会出现失败,典型的redis server未开启或者服务器重启等,需要对异常进行处理。
}
}
public void getRedisVal(){
try{
// 可以直接取出自定义对象数据,需要进行强制转换,我们在config配置时,指定了序列化方式,因此可以强制转换。
Object obj = (Object)valueOperations.get(key);
}catch(RedisConnectionFailureException e){
//
}
}
通过这样的处理,上面的redis就可以简单的进行使用了,当然你需要在你的本地安装redis server端,网上查一下安装教程,有很详细的安装介绍,这里就不再展开了。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--引入lettuce连接池新增的配置 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.3</version>
</dependency>
spring:
redis:
host: localhost
password: jy123123
port: 6379
lettuce:
pool:
# 连接池中的最大空闲连接 默认 8
max-active: 8
# 连接池中的最小空闲连接 默认 0
max-idle: 0
# 连接池最大阻塞等待时间,单位毫秒(使用负值表示没有限制) 默认 -1
max-wait: 1000ms
shutdown-timeout: 100ms
总体上只需要变更这两个地方,其他地方不变,使用方式也和往常一样。(Lettuce和jedis只能选择一种,配置类注释代码在Lettuce无效)