配置
依赖
1
2
3
4
5
6
7
8
|
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
|
1
2
3
4
|
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-redis")
implementation("org.apache.commons:commons-pool2")
}
|
application.yml
配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
server:
port: 8082
servlet:
context-path: /demo
spring:
redis:
# 远程的地址,如果为本地可以不写
host: xx.xx.xx.xx
port: 6379
# 远程密码,可以不写
password: xxxx
# 连接超时时间
timeout: 10000ms
database: 0
lettuce:
pool:
# 连接池最大连接数 ,默认8,写负数表示没有限制
max-active: 20
# 连接池最大空闲连接,默认8
max-idle: 5
# 连接池最大阻塞等待时间
max-wait: 5000ms
# 连接池中的最小空闲连接,默认0
min-idle: 20
|
基础命令
链接本地redis服务
如果有设置密码,则使用来登录
1
|
redis-cli -a <password>
|
代码获取操作对象
直接依赖注入
1
2
|
@Autowired
private lateinit var redisTemplate: StringRedisTemplate
|
存储字符串
类似map,根据key存储字符串,也提供对于数字的增加或减少操作,可以用于统计热度等需要频繁更新的数据,减少数据库访问
客户端命令
1
2
3
4
5
6
7
8
9
10
11
|
# 设置指定 key 的值。
SET key value
# 根据key获取值,如果为空返回(nil)
GET key
# 给 key 设置新 value ,并返回旧值
GETSET key value
# 给key的value加一,必须要是整数
INCR key
|
代码访问
1
2
3
4
5
6
|
// 获取字符串操作对象
val operations = redisTemplate.opsForValue()
operations.get("key")
operations.set("key","value")
// 给定加一,没有的默认为0
operations.increment("key", 1L)
|
List
Redis列表类似与双向队列,可以从左边或者右边插入元素,会保持元素插入顺序。
客户端命令
1
2
3
4
5
6
7
8
9
10
11
|
# 将值添加到列表头部
LPUSH key value
# 获取指定列表范围元素
LRANGE key start stop
# 移除列表元素
LREM key count value
# 移出并获取列表的第一个元素
LPOP key
|
代码访问
1
2
3
4
5
|
val list = redisTemplate.opsForList()
list.leftPush("list", "value0")
list.leftPop("list")
// 是左index
list.index("list", 1)
|
SET
和Java的set类似,使用Hash表实现,不能有重复元素,也是无序的。
客户端命令
1
2
3
4
5
6
7
8
9
10
11
|
# 添加元素
SADD key member
# 获取size
SCARD key
# 返回所有元素
SMEMBERS key
# 获取一个元素
SPOP key
|
代码访问
1
2
3
4
|
val set = redisTemplate.opsForSet()
set.add("set", "value")
val member: Boolean? = set.isMember("set","value")
val members: Set<String>? = set.members("set")
|
ZSET
带有顺序的set,关联一个score来进行排序,score可以重复,元素不可以重复
客户端命令
1
2
3
4
5
|
# 向有序集合添加一个元素,或更新分数
ZADD key score1 member1
# 获取有序集合的成员数
ZCARD key
|
代码访问
1
2
3
4
5
|
val set = redisTemplate.opsForZSet()
set.add("set", "value1", 1.0)
set.add("set", "value2", 1.0)
set.popMin("set")
set.popMax("set")
|
Hash
1
2
|
# 获取存储在哈希表中指定字段的值。
HGET key field
|
1
2
3
|
val map = redisTemplate.opsForHash<String, String>()
map.put("map", "key", "value")
map.get("map","key")
|
Cache
启动类添加注解@EnableCaching
1
2
3
4
5
6
7
8
9
|
@SpringBootApplication
@EnableCaching
public class SpringBootStudyApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootStudyApplication.class, args);
}
}
|
配置类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
package com.jfp.study;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class RedisConfig {
@Bean
RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
redisCacheConfiguration.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
Map<String, RedisCacheConfiguration> redisExpireConfig = new HashMap<>();
//这里设置了一个一分钟的超时配置,如果需要增加更多超时配置参考这个新增即可
redisExpireConfig.put("1min", RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.entryTtl(Duration.ofMinutes(1)).disableCachingNullValues());
RedisCacheManager redisCacheManager = RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration)
.withInitialCacheConfigurations(redisExpireConfig)
.transactionAware()
.build();
return redisCacheManager;
}
}
|
实体类
此处如果直接使用kotlin的data class,需要结合@JsonTypeInfo
1
2
3
4
5
6
7
8
|
public class User {
private String name;
private String uid;
private String email;
//get && set ....
}
|
使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@RestController
@RequestMapping(value = "/user")
public class UserController {
@GetMapping(value = "/info")
@Cacheable(value = "user", key = "#uid")
public User getUser(@RequestParam(value = "uid") String uid) {
System.out.println("getUser====>" + uid);
User user = new User();
user.setUid(uid);
user.setEmail(uid + "@definesys.com");
user.setName(uid + ":" + System.currentTimeMillis());
return user;
}
}
|
校验
1
2
3
4
|
## 输入
curl 192.168.0.108:8082/demo/user/info?uid=jiangker01
## 输出
{"name":"jiangker01: 1647752522128","uid":"jiangker01","email":"jiangker01@definesys.com"}
|
缓存过期
1
2
3
4
5
6
7
8
9
10
11
|
//这里设置了一个一分钟的超时配置,如果需要增加更多超时配置参考这个新增即可
redisExpireConfig.put("1min", RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.entryTtl(Duration.ofMinutes(1)).disableCachingNullValues());
@GetMapping(value = "/info")
@Cacheable(value = "1min", key = "#uid")
public User getUser(@RequestParam(value = "uid") String uid) {
//...
}
|
则存入的数据会在一分钟之后过期。
缓存相关注解
除了Cacheable
还有其他跟缓存相关的注解
1
2
3
4
5
|
public @interface Caching {
Cacheable[] cacheable() default {};
CachePut[] put() default {};
CacheEvict[] evict() default {};
}
|
完整案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
@RestController
@RequestMapping("user")
public class RedisController {
@Autowired
private UserMapper userMapper;
@PostMapping("/add")
@CachePut(value = "neverExpire", key = "#user.uid")
public User add(@RequestBody User user) {
userMapper.insert(user);
return user;
}
@PostMapping("/update")
@CachePut(value = "neverExpire", key = "#user.uid")
public User update(@RequestBody User user) {
return user;
}
@GetMapping("/delete")
@CacheEvict(value = "neverExpire", key = "#uid")
public String delete(@RequestParam(value = "uid") String uid) {
return uid;
}
@GetMapping("/detail")
@Cacheable(value = "neverExpire", key = "#result")
public User deteail(@RequestParam(value = "uid") String uid) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("uid", uid);
return userMapper.selectOne(queryWrapper);
}
}
|
参考
Spring boot 集成Redis