一、理论基础
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-demo
redis:
host: 127.0.0.1
port: 6379
# redis数据库索引
database: 10
password: 123456
lettuce:
pool:
max-active: 10
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: 3000
# 连接池中的最大空闲连接
max-idle: 5
# 连接池中的最小空闲连接
min-idle: 2
# 超时时间(毫秒)
timeout: 10000
2.3 配置类
/**
* Redis配置
* @author smile
*/
@Configuration
public class RedisConfig {
@Resource
private LettuceConnectionFactory connectionFactory;
@Bean
public 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;
}
@Bean
public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForHash();
}
@Bean
public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForValue();
}
@Bean
public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForList();
}
@Bean
public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
return redisTemplate.opsForSet();
}
@Bean
public 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 {
@Autowired
private 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 {
@Autowired
private 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>() {
@Override
public 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