Redis 系列04--Spring Data Redis

上一篇: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存在,但是不是数字,报错
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值