一、如何使用Redis的Java客户端
官方文档: https://redis.io/docs/clients/java/
Java-Redis客户端 | 使用场景 |
---|---|
Jeids | 以Redis命令作为方法名称,学习成本低,简单实现,但是Jedis实例是线程不安全的,多线程环境下需要基于连接池使用。 |
lettuce | Lettuce 是基于Netty实现的,支持同步、异步和响应式编程方式,并且是线程安全的。Redis的哨兵模式、集群模式和管道模式。 |
Redisson | Redisson是基于Redis实现的分布式、可伸缩的Java数据结构集合。包含了诸如Map、Queue、Lock、Semaphore(信号量)、AtomicLong(原子类)等强大功能 |
SpringDataRedis: 一款结合了Jedis和Lettuce的SpringBoot框架整合Redis组件。
二、Jedis
Jedis官网: https://github.com/redis/jedis
Redis的官方也推荐了这种客户端。
(一)引入依赖
java
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.3.1</version>
</dependency>
(二)建立连接
方式一:单点连接
java
private Jedis jedis;
@BeforeEach
void setup() {
//建立连接
jedis = new Jedis("192.168.92.131",6379);
//设置密码
jedis.auth("123321");
//选择数据库
jedis.select(0);
}
@Test
void redisTest(){
//插入数据
String result = jedis.set("name","张三");
System.out.println("result="+result);
//获取数据
String name = jedis.get("name");
System.out.println("name="+name);
}
@AfterEach
void destroy() {
if (jedis != null)
jedis.close();
}
//获取的结果
result=OK
name=张三
方式二:连接池建立连接
java
public class JedisConnectionFactory {
private static final JedisPool jedisPool;
static {
//1、创建连接池配置对象
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//2、配置连接池相关信息
// 最大连接数
jedisPoolConfig.setMaxTotal(8);
// 最大空间连接
jedisPoolConfig.setMaxIdle(8);
// 最小空闲连接
jedisPoolConfig.setMinIdle(0);
// 设置最长等待时间,ms
jedisPoolConfig.setMaxWaitMillis(200);
//3、建立连接池,需要连接池配置,ip,端口,等待时间,密码
jedisPool = new JedisPool(jedisPoolConfig, "192.168.92.131",6379,1000,"123321");
}
public static Jedis getConnection(){
//获取单个连接
return jedisPool.getResource();
}
}
三、SpringDataRedis
SpringData 是 Spring 中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做 SpringDataRedis ,官网地址: https://spring.io/projects/spring-data-redis
- 提供了对不同Redis客户端的整合(Lettuce和Jedis)
- 提供了RedisTemplate统一API来操作Redis
- 支持Redis的发布订阅模块
- 支持Redis哨兵和Redis集群
- 支持基于Lettuce的响应式编程
- 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化
- 支持基于Redis的JDKCollection实现
(一)RedisTemplate
RedisTemplate将不同的数据类型操作API封装到不同类型中。
API | 返回值类型 | 说明 |
---|---|---|
redisTemplate.opsForValue() | ValueOperations | 操作String类型数据 |
redisTemplate.opsForHash() | HashOperations | 操作Hash类型数据 |
redisTemplate.opsForList() | ListOperations | 操作List类型数据 |
redisTemplate.opsForSet() | SetOperations | 操作Set类型数据 |
redisTemplate.opsForZSet() | ZSetOperations | 操作SortedSet类型数据 |
redisTemplate | 通用命令 |
(二)RedisTemplate的基本使用
1、引入依赖
xml
<!--Redis依赖-->
<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、配置redis
yml
spring:
redis:
host: 192.168.92.131
port: 6379
password: 123321
lettuce:
pool:
max-active: 8 #最大连接数
max-idle: 8 #最大空闲连接
min-idle: 0 #最小空闲连接
max-wait: 100 #连接等待时间
3、注入RedisTemplate
java
@Autowired
private RedisTemplate redisTemplate;
4、使用RedisTemplate
java
@Autowired
private RedisTemplate redisTemplate;
public void operateString(){
// 插入一条string类型的数据,存储的格式是Java序列化的格式
redisTemplate.opsForValue().set("name", "李四");
// 读取一条string类型数据
Object name = redisTemplate.opsForValue().get("name");
System.out.println("name = " + name);
}
5、优化RedisTemplate存储序列化的现象
java
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
//1、创建RedisTemplate对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
//2、设置连接工厂
template.setConnectionFactory(connectionFactory);
//3、创建JSON序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//4、设置key的序列化
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
//5、设置Value的序列化
template.setValueSerializer(jsonRedisSerializer);
template.setHashValueSerializer(jsonRedisSerializer);
//6、返回
return template;
}
}
缺点: JSON序列化时会将calss的类型写入json结果中,存入Redis中,带来额外的内存。
为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key 和 value,当需要存储Java对象时,手动完成序列化和反序列化。
Spring默认提供了一个StringRedisTemplate类,它的key和value的序列化方式默认就是String方式,省去自定义RedisTemplate的过程。**
(PS:不如直接用alibaba开源的fastjson,减少学习成本,但要注意的是 在JSON插件的排行中 ,jackson-databind > gson > fastjson,这就说明了问题,fastjson 专注于性能,但安全性不足,gson是保证了安全性,如果可以,在项目中应该使用gson)**
java
@Autowired
private StringRedisTemplate stringRedisTemplate;
//JSON工具
private static final ObjectMapper mapper = new ObjectMapper();
@Test
void testStringTemplate() throws JsonProcessingException {
//准备对象
User user = new User("zain", 23);
//手动序列化
String json = mapper.writeValueAsString(user);
//写入一条数据
stringRedisTemplate.opsForValue().set("jedis:user:2", json);
// 读取数据
String val = stringRedisTemplate.opsForValue().get("jedis:user:2");
// 反序列化
User user1 = mapper.readValue(val, User.class);
}