零、本文纲要
一、Redis官方推荐
二、Jedis使用
三、Spring Data Redis使用
四、Spring Data Redis自定义存储输出
tips:Ctrl + F快速定位所需内容阅读吧。
一、Redis官方推荐
查看:Redis官方推荐Java客户端。
1、对比各个常用客户端
二、Jedis使用
Jedis官方网址:Jedis: Redis Java client designed for performance and ease of use.
1、Jedis单连接
- ① 引入依赖
引入依赖:jedis
,另外为方便测试引入junit
。如下:
<!--jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.1.1</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
- ② 建立连接
@Before
public void beforeJedisTest() {
//1.get connection
jedis = new Jedis("192.168.253.128", 6379);
//2.set password
jedis.auth("123456");
//3.choose database
jedis.select(0);
}
- ③ 测试使用
@Test
public void testString() {
String result = jedis.set("name", "tom");
System.out.println("result is: " + result);
String name = jedis.get("name");
System.out.println("name is: " + name);
}
@Test
public void testHash(){
jedis.hset("user", "name", "jerry");
jedis.hset("user", "age", "24");
Map<String, String> user = jedis.hgetAll("user");
System.out.println("user msg is: " + user);
}
- ④ 释放连接
@After
public void afterJedisTest() {
if (jedis != null) {
//4.release the jedis
jedis.close();
}
}
2、Jedis连接池
- ① 创建连接池工厂类
public class JedisConnectionFactory {
private static final JedisPool jedisPool;
static {
//1.config connection pool
JedisPoolConfig poolConfig = new JedisPoolConfig();
//the max connection count
poolConfig.setMaxTotal(8);
//the max free connection count
poolConfig.setMaxIdle(8);
//the min free connection count
poolConfig.setMinIdle(0);
//the task's timeout : unit ms
poolConfig.setMaxWaitMillis(1000);
//2.connect jedisPool to redis
jedisPool = new JedisPool(poolConfig,
//the host
"192.168.253.128",
//the port
6379,
//the connection's timeout : unit ms
1000,
//redis password
"123456",
//redis database you choose
0);
}
public static Jedis getJedis(){
return jedisPool.getResource();
}
}
- ② 修改jedis的获取方式
将原先单连接的获取方式,改为从工厂获取jedis = JedisConnectionFactory.getJedis();
,如下:
@Before
public void beforeJedisTest() {
//1.get connection
//jedis = new Jedis("192.168.253.128", 6379);
jedis = JedisConnectionFactory.getJedis();
//2.set password
jedis.auth("123456");
//3.choose database
jedis.select(0);
}
三、Spring Data Redis使用
官方文档请看:Spring Data Redis。
1、认识Spring Data Redis
① 提供了对不同Redis客户端的整合(Lettuce和Jedis);
② 提供了RedisTemplate统一API来操作Redis;
③ 支持Redis的发布订阅模型;
④ 支持Redis哨兵和Redis集群;
⑤ 支持基于Lettuce的响应式编程;
⑥ 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化;
⑦ 支持基于Redis的JDKCollection实现。
2、Spring Data Redis基础使用
- ① 引入依赖
Spring Data Redis基础依赖:spring-boot-starter-data-redis
;
连接池依赖:commons-pool2
。
<!--spring_boot_redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--commons_pool2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
其他依赖方便测试使用:
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--spring_boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
- ② application.yml
Ⅰ 配置连接;
Ⅱ 配置连接池:注意连接池一定要有配置才能生效。
spring:
redis:
host: 192.168.253.128
port: 6379
password: 123456
lettuce: # 连接池需要配置才能使用
pool:
max-active: 8 # 最大连接
max-idle: 8 # 最大空闲连接
min-idle: 0 # 最小空闲连接
max-wait: 1000 # 连接等待时间,默认为一直等待'-1'
- ③ 注入RedisTemplate
在SpringBoot的测试类中注入RedisTemplate,如下:
@Autowired
private RedisTemplate redisTemplate;
- ④ 测试连接
@Test
public void testString() {
redisTemplate.opsForValue().set("name","tommy");
String name = (String) redisTemplate.opsForValue().get("name");
System.out.println(name);
}
此时,我们控制台能正常输出:tommy
,但是Redis客户端存储的内容并非我们所设想的,如下:
产生原因:
org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
会对我们传入和取出的内容做序列化。
存在问题:
Ⅰ 可读性差;
Ⅱ 占用更多存储空间。
四、Spring Data Redis自定义存储输出
1、自定义RedisTemplate<String,Object>形式一
- ① 自定义RedisTemplate
Ⅰ 设置key
和hashKey
的形式为String
;
Ⅱ 设置value
和hashValue
的形式为JSON
。
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
//1.create template
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
//2.set connection factory
redisTemplate.setConnectionFactory(redisConnectionFactory);
//3.get serializer
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//4.set key and hashKey string serialize
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
//5.set value and hashValue json serialize
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
//6.return our template
return redisTemplate;
}
- ② 添加Jackson相关依赖
直接启动会报错:nested exception is java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException
,因为Jackson相关的依赖缺失。
<!--jackson_databind-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
- ③ 编写实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
}
- ④ 测试输出对象
@Test
public void testHash(){
redisTemplate.opsForValue().set("user:test",new User("jack",23));
User user = (User) redisTemplate.opsForValue().get("user:test");
System.out.println(user);
}
存在情况:
由于序列化工具类会帮助我们将JSON格式数据转换成实体类对象,在数据存储的时候还存储了类相关的字段,会占用额外空间
。
2、自定义RedisTemplate<String,Object>形式二(推荐)
- ① StringRedisTemplate
StringRedisTemplate是Spring官方提供的类,其key和value的序列化方式默认就是String方式。这样我们可以不用自定义RedisTemplate类。如下:
@Autowired
private StringRedisTemplate stringRedisTemplate;
- ② ObjectMapper
JSON数据和对象的转换工具类,如下:
//JSON mapper tools
private static final ObjectMapper mapper = new ObjectMapper();
- ③ 测试输出对象
需要手动序列化和反序列化JSON数据,String json = mapper.writeValueAsString(user);
以及User gotUser = mapper.readValue(gotJson, User.class);
,如下:
@Test
public void testHash2() throws JsonProcessingException {
//1.prepare user object
User user = new User("bob", 28);
//2.use json tools to serialize user object
String json = mapper.writeValueAsString(user);
//3.set the value into redis
stringRedisTemplate.opsForValue().set("user:test2",json);
//4.get the value from redis
String gotJson = stringRedisTemplate.opsForValue().get("user:test2");
//5.use json tools to unserialize user object
User gotUser = mapper.readValue(gotJson, User.class);
System.out.println(gotUser);
}
对比两种形式:
Ⅰ 形式二不需要手动配置RedisTemplate类,但是需要使用ObjectMapper手动序列化
数据,完成对象转换;
Ⅱ 形式二相比形式一,更节约Redis的存储空间
,因为不需要交由Redis序列化的类来处理。
五、结尾
以上即为Redis客户端的基础使用,感谢阅读。