实战代码(三):Springboot集成redis

一、理论基础

1.1 redis是什么

  • redis是一种key-value的数据库,数据缓存在内存中,也可以持久化到硬盘
  • 一种远程字典服务
  • 高性能、单线程的NoSQL数据库
  • 支持的数据类型
    • String
    • List
    • Set
    • zSet(有序集合)
    • hash

1.2 redis可以做什么

  • 最常用的功能是缓存,将频繁访问的资源提前缓存到内存中加快访问速度,减少网络、IO等损耗
  • 可用做简易版的消息队列
  • redis是单线程的,可以用作计数器,比如接口访问次数等
  • ……

二、实战代码

2.1 依赖引入

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- lettuce pool 缓存连接池 -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.8.0</version>
</dependency>

2.2 配置文件

spring:application:name: spring-boot-redis-demoredis:host: 127.0.0.1port: 6379# redis数据库索引database: 10password: 123456lettuce:pool:max-active: 10# 连接池最大阻塞等待时间(使用负值表示没有限制)max-wait: 3000# 连接池中的最大空闲连接max-idle: 5# 连接池中的最小空闲连接min-idle: 2# 超时时间(毫秒)timeout: 10000

2.3 配置类

/*** Redis配置* @author smile*/
@Configuration
public class RedisConfig {@Resourceprivate LettuceConnectionFactory connectionFactory;@Beanpublic RedisTemplate<String, Object> redisTemplate() {connectionFactory.setShareNativeConnection(false);Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// 视使用情况配置,配置json,则获取的值只能是JSON格式的redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);redisTemplate.setConnectionFactory(connectionFactory);return redisTemplate;}@Beanpublic HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {return redisTemplate.opsForHash();}@Beanpublic ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {return redisTemplate.opsForValue();}@Beanpublic ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {return redisTemplate.opsForList();}@Beanpublic SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {return redisTemplate.opsForSet();}@Beanpublic ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {return redisTemplate.opsForZSet();}
}

2.4 示例代码

2.4.1 StringRedisTemplate

StringRedisTemplate是Springboot Redis已经封装好的一个工具类,支持key、value都是String的数据结构存储。可满足基本的场景

// 注入
@Autowired
private StringRedisTemplate redisTemplate;public void aa() {redisTemplate.opsForValue().set("testSpringbootRedis", "这里可以写各种字符串的值");redisTemplate.opsForValue().increment("aaa");
}
2.4.2 RedisTemplate示例代码
@Component
public class RedisCommonUtils {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 设置缓存失效时间* @param key 键* @param time 过期时间(单位:秒) 如果不大于0则会马上过期* @return 成功返回true*/public boolean expire(String key,long time){return redisTemplate.expire(key, Duration.ofSeconds(time));}/*** 获取过期时间* @param key 键 不能为null* @return 时间(秒) */public long getExpire(String key){return redisTemplate.getExpire(key, TimeUnit.SECONDS);}/*** 判断key是否存在* @param key 键* @return true-存在 false-不存在*/public boolean hasKey(String key){return redisTemplate.hasKey(key);}/*** 删除缓存* @param key 待删除键*/public void del(String key){redisTemplate.delete(key);}/*** 删除多个key* @param keys 待删除的键*/public void delKeys(List<String> keys) {redisTemplate.delete(keys);}
}
2.4.3 ValueOperations示例代码
public class RedisValueUtils {@Autowiredprivate ValueOperations<String, Object> valueOperations;/*** 读取* @param key 键* @return 值*/public Object get(String key){return valueOperations.get(key);}/*** 设置普通缓存* @param key 键* @param value 值*/public void set(String key, Object value) {valueOperations.set(key, value);}/*** 带过期时间的缓存* @param key 键* @param value 值* @param time 过期时间(单位:秒),过期时间必须大于0*/public void set(String key, Object value, long time){if (time > 0) {valueOperations.set(key, value, Duration.ofSeconds(time));}else {throw new RuntimeException("过期时间必须大于0");}}/*** 计数器-递增,每次+1* @param key 键* @return 自增操作后的值*/public long incr(String key){return valueOperations.increment(key);}/*** 计数器-递增* @param key 键* @param delta 每次递增的值* @return 递增操作后的值*/public long incr(String key, long delta){if(delta > 0){return valueOperations.increment(key, delta);}throw new RuntimeException("递增因子必须大于0");}/*** 递减* @param key 键* @return 操作后的值*/public long decr(String key){return valueOperations.decrement(key);}/*** 递减* @param key 键* @param delta 每次减少的值* @return 操作后的值*/public long decr(String key, long delta){if(delta > 0){valueOperations.decrement(key, delta);}throw new RuntimeException("递减因子必须大于0");}
}
2.4.5 scan扫描多个Key的值
public void scan2(String matchKey) {Set<String> keys = new HashSet<>();ScanOptions options = ScanOptions.scanOptions().match(matchKey).count(1000).build();Cursor<String> cursor = (Cursor<String>) redisTemplate.executeWithStickyConnection(redisConnection -> {return new ConvertingCursor<>(redisConnection.scan(options),redisTemplate.getKeySerializer()::deserialize);});cursor.forEachRemaining(key -> {keys.add(key);System.out.println(key);});
}
2.4.6 SessionCallBack 使用一个连接操作多次
redisTemplate.execute(new SessionCallback<Object>() {@Overridepublic Object execute(RedisOperations redisOperations) throws DataAccessException {redisOperations.opsForList().leftPush(REDIS_KEY_LATEST_DATA,CommonGenerator.createData("19.01", "energy-electric"));return null;}
});
2.4.7 其他示例见GitHub

https://github.com/lysmile/spring-boot-demo/tree/master/spring-boot-redis-demo