文章目录
1. 概述
1.1 SpringData
SpringBoot 操作数据都是使用 ——SpringData
以下是 Spring 官网中描述的 SpringData 可以整合的数据源
可以发现 Spring Data Redis
1.2 lettuce
在 SpringBoot 2.X 之后,原来的 Jedis 被替换为了 lettuce
Jedis 和 lettuce 区别
Jedis :采用的是直连的服务,如果有多个线程操作的话是不安全的,就需要使用 Jedis Pool 连接池取解决。问题就会比较多。
lettuce :底层采用 Netty ,实例可以在多个线程中共享,不存在线程不安全的情况。可以减少线程数据了,性能更高。
2. 部分源码
2.1 自动配置
-
找到 spring.factories
spring-boot-autoconfigure-2.3.4.RELEASE.jar → META-INF → spring.factories
-
在 spring.factories 中搜索 redis
可以得出配置 Redis,只需要配置 RedisAutoConfiguration 即可
-
点进 RedisAutoConfiguration
-
点进 RedisProperties
-
回到 RedisAutoConfiguration,观察它做了什么
2.2 Jedis.pool 不生效
-
在 RedisAutoConfiguration 类中的 RedisTemplate 方法需要传递一个 RedisConnectionFactory 参数。点进这个参数
-
这是一个结构,查看实现类
-
查看 Jedis 的实现类,下载源码
会发现 ,这个类中很多没有实现的地方。所以 Jedis Pool 不可以 -
查看 Lettuce 的实现类
没有问题
- 这也说明 SpringBoot 更推荐使用 Lettuce
3. 使用
-
新建一个 SpringBoot 项目,勾选上以下
-
相关依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
-
配置连接,application.yml
# 配置 Redis spring: redis: host: 192.168.142.120 port: 6379
-
测试
// 这就是之前 RedisAutoConfiguration 源码中的 Bean @Autowired private RedisTemplate redisTemplate; @Test void contextLoads() { /** redisTemplate 操作不同的数据类型,API 和 Redis 中的是一样的 * opsForValue 类似于 Redis 中的 String * opsForList 类似于 Redis 中的 List * opsForSet 类似于 Redis 中的 Set * opsForHash 类似于 Redis 中的 Hash * opsForZSet 类似于 Redis 中的 ZSet * opsForGeo 类似于 Redis 中的 Geospatial * opsForHyperLogLog 类似于 Redis 中的 HyperLogLog */ // 除了基本的操作,常用的命令都可以直接通过redisTemplate操作,比如事务…… // 和数据库相关的操作都需要通过连接操作 //RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); //connection.flushDb(); redisTemplate.opsForValue().set("key", "呵呵"); System.out.println(redisTemplate.opsForValue().get("key")); }
4. 序列化
4.1 为什么要序列化
-
新建一个实体类
@Data @AllArgsConstructor @NoArgsConstructor @Component // 实体类序列化在后面加上 implements Serializable public class User { private String name; private String age; }
-
编写测试类,先不序列化
@Test public void test() throws JsonProcessingException { User user = new User("圆","20"); // 使用 JSON 序列化 //String s = new ObjectMapper().writeValueAsString(user); // 这里直接传入一个对象 redisTemplate.opsForValue().set("user", user); System.out.println(redisTemplate.opsForValue().get("user")); }
-
执行结果
如果序列化就不会报错
- 所以一般实体类都要序列化
4.2 为什么要自定义序列化
执行 3. 使用 中的那个测试类,向数据库中插入了一个中文字符串,虽然在 Java 端可以看到返回了中文,但是在 Redis 中查看是一串乱码。
解决这个问题就需要修改默认的序列化规则。
4.2 源码
-
在 RedisAutoConfiguration 类的 redisTemplate 方法中用到了一个 RedisTemplate 的对象
-
点进 RedisTemplate
-
查看这些序列化对象在哪赋值的
- 但我们需要的是 JSON 序列化,所以就需要自定义一个配置类
4.3 使用
-
redisTemplate 模板
@Configuration public class RedisConfig { /** * 编写自定义的 redisTemplate * 这是一个比较固定的模板 */ @Bean @SuppressWarnings("all") public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { // 为了开发方便,直接使用<String, Object> RedisTemplate<String, Object> template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); // Json 配置序列化 // 使用 jackson 解析任意的对象 Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); // 使用 objectMapper 进行转义 ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); // String 的序列化 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // key 采用 String 的序列化方式 template.setKeySerializer(stringRedisSerializer); // Hash 的 key 采用 String 的序列化方式 template.setHashKeySerializer(stringRedisSerializer); // value 采用 jackson 的序列化方式 template.setValueSerializer(jackson2JsonRedisSerializer); // Hash 的 value 采用 jackson 的序列化方式 template.setHashValueSerializer(jackson2JsonRedisSerializer); // 把所有的配置 set 进 template template.afterPropertiesSet(); return template; } }
清空一下数据库
再次执行之前那个插入 User 对象的测试类
发现执行成功,没有报错,并且在 Redis 中也没有转义字符了
-
但是去获取这个对象或者中文字符串的时候还是会显示转义字符,怎么解决?
只需要在启动 Redis 客户端的时候加上 –raw 即可
redis-cli --raw -p 6379