1.Jedis是Redis的一个Java语言客户端连接工具(想要用Java去操作/使用Redis需要一个连接Redis的客户端,Jedis就是这个客户端,另外还有Lettuce、Redisson)。
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2.“Jedis线程不安全,会造成性能损耗,因此用连接池代替”
Q1:如何造成损耗?
Q2:怎么使用连接池?
A1:创建和销毁连接的开销巨大
A2:
public class JedisPoolExample {
private static JedisPool jedisPool;
public static void initPool() {
// 配置连接池
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(128); // 最大连接数
poolConfig.setMaxIdle(64); // 最大空闲连接数
poolConfig.setMinIdle(16); // 最小空闲连接数
poolConfig.setTestOnBorrow(true); // 获取连接时检查有效性
poolConfig.setTestOnReturn(true); // 归还连接时检查有效性
poolConfig.setTestWhileIdle(true); // 在空闲时检查连接有效性
// 创建连接池
// 参数依次为连接池配置、Redis服务器的主机名或IP、Redis服务器的端口、连接超时时间、密码(字符串)
jedisPool = new JedisPool(poolConfig, "localhost", 6379, 10000, “123456”);
}
public static Jedis getJedis() {
return jedisPool.getResource();
}
public static void closeJedis(Jedis jedis) {
if (jedis != null) {
// 归还连接到连接池
jedis.close();
}
}
}
Springboot项目中,在application.yml中配置Redis的连接信息合连接池参数。
spring:
redis:
host: localhost
port: 6379
password: 123456
jedis:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: 3000
3.Spring-Data-Redis
相比Jedis,SpringDataRedis提供更高层次的抽象和整合,支持Spring框架。RedisTemplate是SpringDataRedis的一个工具类,可通过操作Redis。RedisTemplate封装了连接Redis、序列化、Redis 事务等操作。
3.1 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3.2 编写配置
连接池Spring默认使用Lettuce,用Jedis要手动配。
server:
port: 8081
spring:
data:
redis:
#数据库索引
database: 0
#redis 服务器地址
host: 127.0.0.1
#redis 端口
port: 6379
#redis 密码 默认为空
password:
# 链接超时时间
connect-timeout: 10s
#lettuce连接池配置
lettuce:
pool:
# 链接池中最小的空闲链接 默认为0
min-idle: 0
# 链接池中最大的空闲连接 默认为 8
max-idle: 8
#连接池中最大数据库链接数 默认为8
max-active: 8
#连接池最大阻塞等待时间 负值表示没有限制
max-wait: 100ms
3.3 RedisTemplate
@Service
public class TestService {
private final RedisTemplate<String, Object> redisTemplate;
@Autowired
public MyService(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
}
4.RedisTemplate序列化
在将Java对象存储到Redis时,需要转化成字节数组,便于Redis能够正确存储和检索。这个转化的过程称作序列化。不同类型的数据(如字符串、列表、哈希等)在存储时需要统一的序列化方式,以确保数据在存取时能够被正确解析和还原。
RedisTemplate接收任意Object前,会把Object序列化(默认JDK序列化)为字节形式。但是字节可读性差、存储成本高且序列化速度慢。
因此自定义RedisTemplate的序列化方式来解决以上问题。Key用String类序列化,即使用StringRedisSerializer来将字符串进行序列化;Value或Hash用JSON序列化,即使用Jackson2JsonRedisSerializer来将Java对象序列化成JSON格式的字符串,这样可读性强。
@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){
RedisTemplate<String,Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
template.setValueSerializer(jsonRedisSerializer);
template.setHashValueSerializer(jsonRedisSerializer);
return template;
}
但是,以上方法多用了class来帮助反序列化,多占用了空间。因此,可以试试统一用String序列化器,遇到Java对象则手动序列化和反序列化。
void testUser() throws JsonProcessingException {
// 创建对象
User user = new User("Alex",20);
// 手动序列化
String json = mapper.writeValueAsString(user);
// 写入数据
stringRedisTemplate.opsForValue().set("user:200",json);
// 获取数据-默认获取的类型是json字符串
String jsonUser = stringRedisTemplate.opsForValue().get("user:200");
// 手动反序列化
User user1 = mapper.readValue(jsonUser, User.class);
System.out.println("user1 = "+user1);
}
在项目中,可以将手动序列化和手动反序列化封装成一个工具类,直接调用即可了。