SpringBoot - 第二十三章 | Redis的集成和使用(二)
前一章節示範了自動配置的StringRedisTemplate對象進行Redis的讀寫操作,該對像從命名中就可注意到支持的是String類型。有使用過spring-data-redis的一定熟悉RedisTemplate<K, V>接口,StringRedisTemplate就相當於RedisTemplate<String, String>的實作。
除了String類型,開發中我們還經常會在Redis中存儲對象,這時候我們就會想是否可以使用類似RedisTemplate<String, Customer>來初始化並進行操作。但是Spring Boot並不支持直接使用,需要我們自己實作RedisSerializer接口來對傳入對象進行序列化和反序列化,下方會通過一個實例來完成對象的讀寫操作。
Docker Redis準備
1
| docker run --name myredis -p 6379:6379 -d redis:3.2 redis-server --appendonly yes
|
命令說明:
1 2 3
| --name myredis:容器取名為myredis -p 6379:6379 : 將容器的6379端口映射到主機的6379端口 redis-server --appendonly yes : 在容器執行redis-server啟動命令,並打開redis持久化配置
|
相關配置
Spring Boot提供的資料訪問框架Spring Data Redis基於Jedis。可以通過引入spring-boot-starter-redis來配置依賴關係。
加入pom的依賴
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
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </exclusion> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency>
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>
|
參數配置
在src/main/resources/application.properties中配置Redis服務端訊息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
spring.redis.database=0
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.timeout=1000
|
建立 Customer
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
package com.jj.learning.springboot.chapter23.domain;
import java.io.Serializable;
public class Customer implements Serializable {
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
private String name;
private Integer age;
public Customer(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
建立 RedisObjectSerializer (實現對象的序列化接口)
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
package com.jj.learning.springboot.chapter23;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.serializer.support.DeserializingConverter;
import org.springframework.core.serializer.support.SerializingConverter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
public class RedisObjectSerializer implements RedisSerializer<Object> {
private Converter<Object, byte[]> serializer = new SerializingConverter();
private Converter<byte[], Object> deserializer = new DeserializingConverter();
static final byte[] EMPTY_ARRAY = new byte[0];
public Object deserialize(byte[] bytes) {
if (isEmpty(bytes)) {
return null;
}
try {
return deserializer.convert(bytes);
} catch (Exception ex) {
throw new SerializationException("Cannot deserialize", ex);
}
}
public byte[] serialize(Object object) {
if (object == null) {
return EMPTY_ARRAY;
}
try {
return serializer.convert(object);
} catch (Exception ex) {
return EMPTY_ARRAY;
}
}
private boolean isEmpty(byte[] data) {
return (data == null || data.length == 0);
}
}
建立 RedisConfig (配置針對Customer的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
package com.jj.learning.springboot.chapter23;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.jj.learning.springboot.chapter23.domain.Customer;
@Configuration
public class RedisConfig {
@Bean
JedisConnectionFactory jedisConnectionFactory() {
return new JedisConnectionFactory();
}
@Bean
public RedisTemplate<String, Customer> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Customer> template = new RedisTemplate<String, Customer>();
template.setConnectionFactory(jedisConnectionFactory());
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new RedisObjectSerializer());
return template;
}
}
測試
撰寫測試
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
package com.jj.learning.springboot.chapter23;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import com.jj.learning.springboot.chapter23.domain.Customer;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter23ApplicationTests {
@Autowired
private RedisTemplate<String, Customer> redisTemplate;
@Test
public void test() throws Exception {
// 新增/保存Customer
Customer customer = new Customer("J.J.Huang", 18);
redisTemplate.opsForValue().set(customer.getName(), customer);
customer = new Customer("K.K.Huang", 28);
redisTemplate.opsForValue().set(customer.getName(), customer);
customer = new Customer("L.L.Huang", 38);
redisTemplate.opsForValue().set(customer.getName(), customer);
// 取得並比對年齡
Assert.assertEquals(18, redisTemplate.opsForValue().get("J.J.Huang").getAge().longValue());
Assert.assertEquals(28, redisTemplate.opsForValue().get("K.K.Huang").getAge().longValue());
Assert.assertEquals(38, redisTemplate.opsForValue().get("L.L.Huang").getAge().longValue());
}
}
測試結果

我們可以透過Redis-cli指令去查詢看這個是否有寫入

註:以上參考了
SpringBoot2.0+整合redis,使用 RedisTemplate操作redis
oKong 的 SpringBoot | 第十一章:Redis的集成和简单使用文章。
程序猿DD-翟永超 的 Spring Boot中使用Redis数据库 文章。