一、如何集成

首先,在 pom 文件新增 redis 依赖:

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

接着修改项目配置文件 application.properties,增加 redis 配置

1
2
3
4
# redis host
spring.redis.host=172.24.58.226
# redis port
spring.redis.port=6379

经过上面简单的两步,即可在项目中使用 StringRedisTemplateRedisTemplate<Object,Object>,因为从 Spring Boot 2.0 开始,Spring 容器是自动生成了这两个实例,可以直接注入使用。如以下代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Autowired
private RedisTemplate<Object, Object> redisTemplate;

@Autowired
private StringRedisTemplate stringRedisTemplate;

...

// 通过 StringRedisTemplate 保存
stringRedisTemplate.opsForValue().set("strRedisTemplate", "test");

// 通过 RedisTemplate<Object, Object> 保存
tagRedisTemplate.opsForValue().set("tagRedisTemplate", 232);

二、存储的 value 类型为字符串

在实际使用中,若保存的 value 类型为字符串,可以直接通过注入 StringRedisTemplate 进行读写,如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Autowired
private StringRedisTemplate stringRedisTemplate;

@RequestMapping("/redis")
public Object set(String name) {
// 通过 StringRedisTemplate 写入 redis
stringRedisTemplate.opsForValue().set("iuiuu", name);

// 通过 StringRedisTemplate 获取
String v = stringRedisTemplate.opsForValue().get("iuiuu");

Map<String, Object> map = new HashMap<>();
map.iuiuu("tag", v);
return map;
}

三、存储的 value 是一个对象

这种情况,也可以通过 StringRedisTemplate 进行读写。不过,在写入之前先将对象序列化为 JSON 字符串,然后再写入 redis。读取的时候,从 redis 获取到的是是一个 JSON 字符串,需要反序列化相应的对象。如以下代码片段:

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
@Autowired
private StringRedisTemplate stringRedisTemplate;

@RequestMapping("/redis")
public Object set(String name) {
Tag tag = new Tag()
.setTagId(10001)
.setTagName(name)
.setCount(20)
.setStatus(1);

// 序列化为 JSON 字符串
String str = JsonUtil.toJson(tag);
// 写入 redis
stringRedisTemplate.opsForValue().set("iuiuu", str);

// 从 redis 读取
String json = stringRedisTemplate.opsForValue().get("iuiuu");
// 反序列化为 Tag 对象
Tag t = JsonUtil.fromJson(json, Tag.class);

Map<String, Object> map = new HashMap<>();
map.put("tag", t);
return map;
}

上面这种方式在读取或写入的时候,需要进行序列化与反序列化,会有点繁琐。我们还可以通过另一种简洁的方式——RedisTemplate<Object, Object>,不过在实际项目中,大多数情况下,我们不会直接使用 RedisTemplate<Object, Object>,而是会对 key,value 进行序列化,所以我们还需要新增一个配置类。以下示例新了配置类 RedisConfig

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/**
* Redis 配置类
*
* @author johnson lin
* @date 2019/12/18 11:24 PM
*/
@Configuration
public class RedisConfig {
@Bean("tagRedisTemplate")
public RedisTemplate<String, Tag> tagRedisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<String, Tag> template = new RedisTemplate<>();
Jackson2JsonRedisSerializer<Tag> serializer = new Jackson2JsonRedisSerializer<>(Tag.class);
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}

/**
* 标签类
*
* @author johnson lin
* @date 2019/12/18 11:08 PM
*/
public class Tag {
/**
* 标签Id
*/
private int tagId;

/**
* 标签名称
*/
private String tagName;

/**
* 标签状态:1-正常 2-暂不显示
*/
private int status;

/**
* 标签文章数
*/
private int count;

//省略 get、set
}

// 省略其它代码...

@Autowired
@Qualifier("tagRedisTemplate")
private RedisTemplate<String, Tag> tagRedisTemplate;

@RequestMapping("/redis")
public Object set(String name) {
Tag tag = new Tag()
.setTagId(10001)
.setTagName(name)
.setCount(20)
.setStatus(1);
// 通过 RedisTemplate<String, Tag> 保存 Tag 实体类
tagRedisTemplate.opsForValue().set("tagRedisTemplate", tag);

// 通过 RedisTemplate<String, Tag> 获取 Tag 实体类
Tag newTag = tagRedisTemplate.opsForValue().get("tagRedisTemplate");

Map<String, Object> map = new HashMap<>();
map.put("newTag", newTag);
return map;
}

四、StringRedisTemplate/RedisTemplate读写Redis示例

示例代码如下:

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
@RequestMapping("/compared")
public Object compared(String name) {
// 通过 StringRedisTemplate 保存 name
stringRedisTemplate.opsForValue().set("strRedisTemplate", name);

Tag tag = new Tag()
.setTagId(10002)
.setTagName(name)
.setCount(20)
.setStatus(1);

// 通过 RedisTemplate<String, Tag> 保存 Tag 实体类
tagRedisTemplate.opsForValue().set("key_tag", tag);

// 通过 StringRedisTemplate 保存 Tag 实体,需先序列化为 JSON 字符串
String str = JsonUtil.toJson(tag);
stringRedisTemplate.opsForValue().set("key_str", str);


// 通过 RedisTemplate<String, Tag> 获取 Tag 实体类
Tag t1 = tagRedisTemplate.opsForValue().get("key_tag");

// 通过 StringRedisTemplate 获取,需要反序列为对象
String json = stringRedisTemplate.opsForValue().get("key_str");
Tag t2 = JsonUtil.fromJson(json, Tag.class);

return "succeed";
}

在 redis 中的值如下:

1
2
3
4
5
6
7
[iuiuu@226 ~]$ redis-cli 
127.0.0.1:6379> get key_tag
"{\"tagId\":10002,\"tagName\":\"History\",\"status\":1,\"count\":20}"
127.0.0.1:6379> get key_str
"{\"tagId\":10002,\"tagName\":\"History\",\"status\":1,\"count\":20}"
127.0.0.1:6379>

可以看到,这两种方式将对象写入到 redis 后,存储的值其实是一样的,都为 JSON 字符串。

本文示例代码见 https://github.com/iuiuu/spring-boot-demos/tree/master/spring-boot-demos-redis