SpringBoot使用RedisTemplate存储对象

概述

redis是最常用的缓存工具。SpringBoot2.x中将默认连接池更改为了 Lettuce。近期需要用redis存储对象,网上的大多不靠谱。以下为笔记。

pom.xml

springboot版本为 2.3.0.RELEASE

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.8.0</version>
</dependency>

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* @author 当我遇上你
* @公众号 当我遇上你
* @since 2020-05-27
*/
public class RedisObjectSerializer implements RedisSerializer<Object> {

static final byte[] EMPTY_ARRAY = new byte[0];

@Override
public Object deserialize(byte[] bytes) {
if (isEmpty(bytes)) {
return null;
}
ObjectInputStream oii = null;
ByteArrayInputStream bis = null;
bis = new ByteArrayInputStream(bytes);
try {
oii = new ObjectInputStream(bis);
Object obj = oii.readObject();
return obj;
} catch (Exception e) {

e.printStackTrace();
}
return null;
}

@Override
public byte[] serialize(Object object) {
if (object == null) {
return EMPTY_ARRAY;
}
ObjectOutputStream obi = null;
ByteArrayOutputStream bai = null;
try {
bai = new ByteArrayOutputStream();
obi = new ObjectOutputStream(bai);
obi.writeObject(object);
byte[] byt = bai.toByteArray();
return byt;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

private boolean isEmpty(byte[] data) {
return (data == null || data.length == 0);
}
}

redisTemplate配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* @author 当我遇上你
* @公众号 当我遇上你
* @since 2020-05-27
*/
@Configuration
public class RedisConfig {

@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {

StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
RedisObjectSerializer redisObjectSerializer = new RedisObjectSerializer();

RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(stringRedisSerializer);
template.setValueSerializer(redisObjectSerializer);
return template;
}

}

序列化为json

1
2
3
4
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
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
@Configuration
public class RedisConfiguration {

@Bean("redisTemplate")
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {

// 设置序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);// key序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
redisTemplate.afterPropertiesSet();
return redisTemplate;

}
}

测试

随便写一个实体对象

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
/**
* @author 当我遇上你
* @公众号 当我遇上你
* @since 2020-05-27
*/
public class User implements Serializable {

private String username;
private String password;

public User(String username, String password) {
this.username = username;
this.password = password;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}

单元测试

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
/**
* @author 当我遇上你
* @公众号 当我遇上你
* @since 2020-05-27
*/
@SpringBootTest
class UserTest {

@Autowired
private RedisTemplate<String,Object> template;

/**
* User{username='admin', password='123456'}
*/
@Test
public void saveValue() {
User u=new User("admin", "123456");
template.opsForValue().set(u.getUsername(), u);
User result = (User) template.opsForValue().get(u.getUsername());
System.out.println(result.toString());
}

/**
* [123456, admin]
*/
@Test
public void saveHash(){

User u=new User("admin", "123456");
HashMap<Object, Object> objectHashMap = new HashMap<>();
objectHashMap.put("username", u.getUsername());
objectHashMap.put("password", u.getPassword());
template.opsForHash().putAll("hash", objectHashMap);

List<Object> myCache = template.opsForHash().values("hash");
System.out.println(myCache);
}

/**
* User{username='admin', password='123456'}
*/
@Test
public void saveList() {
User user = new User("admin", "123456");
template.opsForList().leftPush("list", user);
Object rightPop = template.opsForList().rightPop("list");
System.out.println(rightPop);
}

}

总结

本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】支持。