上一篇:Redis 系列03--Redis Jedis 客户端_fengxianaa的博客-CSDN博客
1. 介绍
Spring Data Redis 简单说就是 spring 对 redis 操作的封装,其中 RedisTemplate 提供更加便捷的操作。
我们都知道,jedis的方法名其实就是一个个redis命令,但其实reids命令可以分成不同的组,
比如:字符串命令、List命令、Set命令等,
RedisTemplate 包含各种对redis的操作,并将不同数据类型的API,封装到不同的类中
2. maven 依赖
创建一个spring boot 项目,添加以下依赖
<!-- spring data redis 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- spring boot 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
3. properties
spring.redis.host=192.168.56.103
spring.redis.port=6379
#lettuce 也是redis的客户端,spring boot 2.X,默认使用lettuce作为redis客户端
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-wait=-1
4. RedisTemplate 入门
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class RedisTemplateTest {
//直接注入
@Autowired
private RedisTemplate redisTemplate;
/**
* 对字符串的操作
*/
@Test
public void testString(){
ValueOperations valueOperation = redisTemplate.opsForValue();
valueOperation.set("fengxiansheng","hahahahhah");
Object fengxiasnheng = valueOperation.get("fengxiansheng");
System.out.println(fengxiasnheng);
}
}
结果:
5. RedisTemplate 序列化
1. 问题
在上面,使用 redisTemplate 设置了一个 fengxiansheng 的key,下面用命令行查看一下
可以发现,命令行查看的结果,跟我们在代码中设置的有很大的差距
这是因为 redisTemplate 在执行set方法的时候,对 key、value 进行了序列化
其实细心的朋友在调用 ValueOperations 的 set 方法的时候可以发现,参数是 Object 类型
但是 redis 是不支持 Object ,所以 redisTemplate 就,对 key 、value 进行了序列化,
在 RedisTemplate 源码中,可以看到有4个序列化器
而默认情况下,用的是 JdkSerializationRedisSerializer,把key 、value 序列化为字节
我们可以跟踪源码看一下,点进去 set 方法
可以看到就是:JdkSerializationRedisSerializer
但是这种序列化方式明显有问题
- 可读性差
- 会额外占用不必要的内存
2. 自定义 RedisTemplate
所以这时候就需要修改默认的序列化器
查看 RedisSerializer 的实现,可以看到有GenericJackson2JsonRedisSerializer、StringRedisSerializer
针对我们存储的数据而言,key一般都是String类型,所以 key的序列化可以用 StringRedisSerializer
而 value 可能是对象类型,所以用 GenericJackson2JsonRedisSerializer
自定义 RedisTemplate
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
//创建 RedisTemplate 对象
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
//设置 连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
//设置key的序列化
redisTemplate.setKeySerializer(StringRedisSerializer.UTF_8);
redisTemplate.setHashKeySerializer(StringRedisSerializer.UTF_8);
//设置 value 的序列化
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
return redisTemplate;
}
}
然后重新执行代码
3. 存储对象
新建User类
public class User {
public String name;
public int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
新建测试方法
@Test
public void testObj(){
ValueOperations valueOperation = redisTemplate.opsForValue();
User user = new User();
user.name = "冯先生";
user.age = 18;
valueOperation.set("user", user);
Object obj = valueOperation.get("user");
System.out.println(obj);
}
运行结果:
命令行,查看redis
注意:name的值,并不是乱码,而是unicode编码
想要看到汉字,使用 redis-cli --raw 连接redis
4. StringRedisTemplate
它继承RedisTemplate,但是要求key、value都得是字符串,而且它的序列化器都是StringRedisSerializer,这就需要,我们自己把对象转换为String,
这种方式更灵活,在实际工作中更容易发现和解决问题,很受欢迎
在 pom.xml 中添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
修改代码
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void testStr(){
ValueOperations valueOperation = stringRedisTemplate.opsForValue();
User user = new User();
user.name = "冯先生";
user.age = 18;
valueOperation.set("user", JSONObject.toJSONString(user));
String obj = (String) valueOperation.get("user");
User user1 = JSONObject.parseObject(obj, User.class);
System.out.println(user1);
}
5. 常用API
因为 RedisTemplate 的方法名跟 redis 的命令不对应,这里列举一些常用的方法
1. redisTemplate
- expire("fengxiansheng", 5, TimeUnit.SECONDS)
- 设置 fengxiansheng 这个key,5秒钟过期,成功,返回true,失败,返回false
- key不存在也会返回false
- getExpire("fengxiansheng")
- 获取 key 还有多少秒过期,key不存在返回 -2,key没有过期时间,返回-1
- delete("fengxiansheng")
- 删除置顶key,成功,返回true,失败,返回false
- key不存在也会返回false
2. ValueOperations
- set("fengxiansheng", "hahaha", 5, TimeUnit.SECONDS))
- 设置 fengxiansheng 这个key,值是:hahaha,且5秒钟过期
- setIfAbsent("fengxiansheng", "hahaha", 5, TimeUnit.SECONDS)
- 如果key不存在,设置这个key值是:hahaha,且5秒钟过期
- 成功,返回true,失败,返回false
- getAndSet("fengxiansheng", "aaaaaa")
- 给 fengxiansheng 这个key,设置新的值,返回老的值
- 如果key不存在,返回 null
- increment("fengxiansheng")
- 对指定的key,值+1,返回+1后的值
- key不存在,认为初始值是0
- key存在,但是不是数字,报错
- decrement("fengxiansheng")
- 对指定的key,值-1,返回-1后的值
- key不存在,认为初始值是0
- key存在,但是不是数字,报错