(三)、Redis 的客户端
在Redis官网中提供了各种语言的客户端,地址: https://redis.io/resources/clients/#java
1.使用Jedis
Jedis的官网: https://github.com/redis/jedis
- 引入依赖
<!-- 导入jedis--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
- 建立连接
@Test void test3(){ // 链接 Jedis jedis = new Jedis("127.0.0.1", 6379); jedis.auth("121788"); // 选择库 jedis.select(0); // 测试是否链接成功 System.out.println(jedis.ping()); jedis.set("username1","123456"); System.out.println(jedis.get("username")); // 释放链接 jedis.close(); }
2.Jedis 连接池
Jedis 本身线程是不安全的,并且频繁的创建和销毁会有性能损耗,因此我们推荐大家使用Jedis连接池的直连方式。
Redis作为一款主流的高性能NoSQL内存数据库,现在被越来越多的开发者使用。然而,由于Redis是单线程模式,大量的连接会导致CPU和内存资源耗用。为了提高Redis的性能,线程池是一项很好的解决方案。
线程池是将Redis连接包装成线程池,可以提前分配一定数量的线程来进行处理,这样就可以有效的提升Redis的性能。有了线程池,开发者就可以利用它在Redis中分布式读写数据,以改进系统的性能。同时线程池还可以有效地减少资源的消耗。
可以看出,结合Redis的线程池和数据模型进行优化,可以大大提升Redis的性能。如果正确地配置线程池和当前Redis环境,不仅可以提高性能,而且可以有效的降低服务器的资源消耗,再搭配合理的缓存策略,真正实现简单优化,大幅提升的效果。
redis: host: 127.0.0.1 port: 6379 password: 121788 client-type: jedis jedis: pool: # 连接池中的最大空闲连接 max-idle: 8 # 连接池中的最小空闲连接 min-idle: 10 # 连接池最大连接数(使用负值表示没有限制) max-active: 100 # 连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1
连接池配置源码: RedisProperties.java
我们创建Jedis会自动找到这里
3.SpringDataRedis (需要序列化)
SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SprinaDataRedis官网地址: https://spring.io/projects/spring-data-redis
- 提供了对不同Redis客户端的整合 (Lettuce和Jedis)
- 提供了
RedisTemplate类似于(JdbcTemplate)
统一API来操作Redis - 支持Redis的发布订阅模型
- 支持Redis哨兵和Redis集群
- 支持基于Lettuce的响应式编程
- 支持基于
JDK、JSON、字符串、Spring对象的数据序列化及反序列化
- 支持基于Redis的JDKCollection实现
SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:
(1).快速入门
1.导入依赖
<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>
2.配置数据
spring: redis: host: 127.0.0.1 port: 6379 password: 121788 client-type: jedis jedis: pool: # 连接池中的最大空闲连接 max-idle: 10 # 连接池中的最小空闲连接 min-idle: 8 # 连接池最大连接数(使用负值表示没有限制) max-active: 100 # 连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1
3.自动注入
@Resource RedisTemplate redisTemplate;
4.测试实现
@Test void test4(){ redisTemplate.opsForValue().set(JSON.toJSONString("username4"),JSON.toJSONString("李明")); System.out.println(redisTemplate.opsForValue().get(JSON.toJSONString("username4"))); }
(2).RedisTemplate的序列化RedisSerizal
配置我们默认的序列化器
package com.jsxs.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializer; import java.net.UnknownHostException; /** * @Author Jsxs * @Date 2023/7/20 13:56 * @PackageName:com.jsxs.config * @ClassName: RedisConfig * @Description: TODO * @Version 1.0 */ @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { // 将template 泛型设置为 <String, Object> RedisTemplate<String, Object> template = new RedisTemplate(); // 连接工厂,不必修改 template.setConnectionFactory(redisConnectionFactory); /* * 序列化设置 */ // key、hash的key 采用 String序列化方式 template.setKeySerializer(RedisSerializer.string()); template.setHashKeySerializer(RedisSerializer.string()); // value、hash的value 采用 Jackson 序列化方式 template.setValueSerializer(RedisSerializer.json()); template.setHashValueSerializer(RedisSerializer.json()); template.afterPropertiesSet(); return template; } }
4.StringRedisTemplate (不需要序列化)
尽管JSON的序列化满足我们的需求,但依然存在一些问题,如图:
@Test void test4(){ Admin admin = adminMapper.selectById(1); redisTemplate.opsForValue().set(JSON.toJSONString("username7"),JSON.toJSON(admin)); System.out.println(redisTemplate.opsForValue().get(JSON.toJSONString("username7"))); }
为了在反序列化时知道对象的类型,JSON序列化器会将类的class类型写入json结果中,存入Redis,会带来额外的内存
开销。
为了节省内存空间,我们并不会使用]SON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储]ava对象时,手动完成对象的序列化和反序列化。
Spring默认提供了一个StringRedisTemplate类,它的key和value的序列化方式默认就是String方式。省去了我们自定义RedisTemplate配置的过程:
@Resource StringRedisTemplate stringRedisTemplate;
@Test void test5(){ Admin admin = adminMapper.selectById(1); stringRedisTemplate.opsForValue().set(JSON.toJSONString("username8"),JSON.toJSONString(admin)); System.out.println(JSON.parse(stringRedisTemplate.opsForValue().get(JSON.toJSONString("username8")))); }