SpringDataRedis
StringRedisTemplate 是 Spring Data Redis 里专门操作字符串类型数据的工具类,比 RedisTemplate 更适合初学和普通字符串操作
| 作用 |
说明 |
| 简化 Redis 操作 |
不用手动创建 Jedis 连接 |
| 整合 Spring Boot |
可以通过配置文件连接 Redis |
| 支持多种数据类型 |
String、Hash、List、Set、ZSet |
| 支持连接池 |
底层可使用 Lettuce 或 Jedis |
| 支持对象存储 |
可以把 Java 对象存入 Redis |
| 支持序列化 |
可以配置 key 和 value 的序列化方式 |
| Redis 数据类型 |
Spring Data Redis 操作对象 |
| String |
opsForValue() |
| Hash |
opsForHash() |
| List |
opsForList() |
| Set |
opsForSet() |
| SortedSet / ZSet |
opsForZSet() |
示例
1 2 3 4 5 6 7 8 9
| <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 5 6 7 8 9 10 11 12 13 14
| spring: data: redis: host: 10.211.55.3 port: 6379 password: 123123 database: 0 lettuce: pool: max-active: 8 max-idle: 8 min-idle: 0 max-wait: 100ms
|
1 2 3 4 5 6 7 8 9 10
| @Autowired private RedisTemplate redisTemplate;
@Test void RedisTest() { redisTemplate.opsForValue().set("name", "aron"); Object name = redisTemplate.opsForValue().get("name"); System.out.println(name); }
|
序列化方式
RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,因此写入到redis中的数据是这样的: \xac\xed\x00\x05t\x00\x04aron
缺点:可读性差,内存占用较大
RedisTemplate的两种序列化实践方案:
- 方案一:
自定义RedisTemplate
修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer
- 方案二:
使用StringRedisTemplate
写入Redis时,手动把对象序列化为JSON
读取Redis时,手动把读取到的JSON反序列化为对象
方案一
1 2 3 4 5
| <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 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
| //手动设置序列化方式 @Configuration public class RedisConfig {
@Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
// 1. 创建 RedisTemplate 对象 RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 2. 设置 Redis 连接工厂 // 连接工厂由 Spring Boot 根据 application.yml 自动创建 redisTemplate.setConnectionFactory(connectionFactory);
// 3. 创建 String 序列化器 // 用来序列化 key,例如 name、user:1、shop:1 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// 4. 创建 JSON 序列化器 // 用来序列化 value,把 Java 对象转成 JSON 字符串存入 Redis Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
// 5. 创建 ObjectMapper 对象 // ObjectMapper 是 Jackson 提供的 JSON 转换工具 ObjectMapper objectMapper = new ObjectMapper();
// 6. 设置对象所有属性都可以被序列化 // 包括 private 修饰的字段 objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 7. 启用类型信息 // 这样反序列化时,Redis 可以知道原来的 Java 对象类型 objectMapper.activateDefaultTyping( objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL );
// 8. 把 ObjectMapper 设置给 JSON 序列化器 jsonRedisSerializer.setObjectMapper(objectMapper);
// 9. 设置 key 的序列化方式 // Redis 中普通 key 使用字符串序列化 redisTemplate.setKeySerializer(stringRedisSerializer);
// 10. 设置 value 的序列化方式 // Redis 中普通 value 使用 JSON 序列化 redisTemplate.setValueSerializer(jsonRedisSerializer);
// 11. 设置 Hash 类型 key 的序列化方式 // 例如 hset user:1 name Aron 中的 user:1 redisTemplate.setHashKeySerializer(stringRedisSerializer);
// 12. 设置 Hash 类型 value 的序列化方式 // 例如 hset user:1 name Aron 中的 Aron redisTemplate.setHashValueSerializer(jsonRedisSerializer);
// 13. 初始化 RedisTemplate redisTemplate.afterPropertiesSet();
// 14. 返回配置好的 RedisTemplate return redisTemplate; } }
|
方案二
为了节省内存空间,我们并不会使用SON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储ava对象时,手动完成对象的序列化和反序列化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @SpringBootTest public class RedisTest {
@Autowired private StringRedisTemplate stringRedisTemplate;
@Test void testString() { stringRedisTemplate.opsForValue().set("name", "Aron");
String name = stringRedisTemplate.opsForValue().get("name");
System.out.println(name); } }
|
反序列化
1 2 3 4 5 6
| <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.32</version> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @Data @NoArgsConstructor @AllArgsConstructor public class User { private String name; private Integer age; }
@Test void testUser() throws Exception { User user = new User("Aron", 20); //手动序列化 String json = mapper.writeValueAsString(user); //写入数据 stringRedisTemplate.opsForValue().set("user:1", json); //获取数据 String result = stringRedisTemplate.opsForValue().get("user:1"); //手动反序列化 User userResult = mapper.readValue(result, User.class);
System.out.println(userResult); }
|