Jedis,SpringDataRedis

快速入门

导入依赖

        <!--jedis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.7.0</version>
        </dependency>
        <!--单元测试-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.7.0</version>
            <scope>test</scope>
        </dependency>

测试代码

package com.example;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;

public class JedisTest {
    private Jedis jedis;

    @BeforeEach
    void setUp() {
        jedis = new Jedis("192.168.168.168", 6379);
        jedis.auth("123456");
        jedis.select(0);
    }

    @Test
    void test() {
        String name = jedis.get("name");
        System.out.println(name);
    }

    @AfterEach
    void tearDown() {
        if(jedis != null){
            jedis.close();
        }
    }
}

jedis连接池

Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此推荐大家使用Jedis连接池代替Jedis的直连方式。

package com.example.utils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisConnectionFactory {
    private static JedisPool jedisPool;
    //在类加载时执行
    static {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(8);//最大连接数
        poolConfig.setMaxIdle(8);//最大空闲连接数
        poolConfig.setMinIdle(0);//最小空闲连接数
        poolConfig.setMaxWaitMillis(1000);//最大等待时间 (单位:毫秒)
        jedisPool = new JedisPool(poolConfig, "192.168.168.168", 6379, 1000, "123456");
    }//连接超时时间 1000毫秒
    public static Jedis getJedis() {
        return jedisPool.getResource();
    }
}

修改后这样获取jedis对象

    @BeforeEach
    void setUp() {
        jedis = JedisConnectionFactory.getJedis();
        jedis.auth("123456");
        jedis.select(0);
    }

SpringDataRedis

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:Spring Data Redis

- 提供了对不同Redis客户端的整合(Lettuce和Jedis)
- 提供了RedisTemplate统一API来操作Redis
- 支持Redis的发布订阅模型
- 支持Redis哨兵和Redis集群
- 支持基于Lettuce的响应式编程
- 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化
- 支持基于Redis的JDKCollection实现

快速入门

导入依赖

        <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>

配置redis

spring:
  data:
    redis:
      host: 192.168.168.168
      port: 6379
      password: 123456
      database: 0
      lettuce:
        pool:
          max-active: 8
          max-idle: 8
          min-idle: 0
          max-wait: 100ms

测试

package com.example;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;

@SpringBootTest
public class RedisTemplateTest {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void test01() {
        redisTemplate.opsForValue().set("name","lihua");
        System.out.println(redisTemplate.opsForValue().get("name"));
    }
}

自定义序列化

jdk序列化(默认的序列化方式)的问题

 进行如上测试后,发现并没有修改key为name的值为lihua,而是出现了这样的结果

原因如下

RedisTemplate可以接收任意Object作为值写入Redis:

只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的:


缺点:
- 可读性差
- 内存占用较大

***************************************************

自定义序列化方式为json序列化

首先写一个RedisTemplate的配置

package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

@Configuration
public class RedisTemplateConfig {
    @Bean
    //RedisConnectionFactory是spring内置的,在项目启动时会自动装配,因此作为参数传入即可
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        //创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //设置连接工厂
        template.setConnectionFactory(factory);
        //创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        //设置key的序列化   RedisSerializer是redis的一个序列化器
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        //设置value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);
        //返回
        return template;
    }
}

在springboot项目启动时,这个bean就会被加载

重新测试

    @Test
    public void test01() {
        redisTemplate.opsForValue().set("name","zhaosi");
        System.out.println(redisTemplate.opsForValue().get("name"));
    }

测试结果如下

 

符合我们的预期

*********************************

也可以存入自定义对象

    @Test
    public void test02() {
        User u1 = new User(1, "laoda", 24);
        redisTemplate.opsForValue().set("user:001", u1);
    }
    @Test
    public void test03() {
        User user = (User) redisTemplate.opsForValue().get("user:001");
        System.out.println(user);
    }

测试结果如下

整体可读性有了很大提升,并且能将Java对象自动的序列化为JSON字符串,并且查询时能自动把JSON反序列化为Java对象。不过,其中记录了序列化时对应的class名称,目的是为了查询时实现自动反序列化。这会带来额外的内存开销。  (我们将用StringRedisTemplate进行改进)

SpringRedisTemplate 

为了节省内存空间,我们可以不使用JSON序列化器来处理value,而是统一使用String序列化器(这样value就不用存储对象的字节码文件了),要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。

因为存入和读取时的序列化及反序列化都是我们自己实现的,SpringDataRedis就不会将class信息写入Redis了。

这种用法比较普遍,因此SpringDataRedis就提供了RedisTemplate的子类:StringRedisTemplate,它的key和value的序列化方式默认就是String方式。

导入jackson依赖

        <!--Jackson依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

省去了我们自定义RedisTemplate的序列化方式的步骤,而是直接使用就好了

@SpringBootTest
public class StringRedisTemplateTest {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private static final ObjectMapper mapper = new ObjectMapper();

    @Test
    public void test() throws JsonProcessingException {
        User u1 = new User(2, "赵四", 25);
        //手动序列化
        String json = mapper.writeValueAsString(u1);
        System.out.println("序列化后的json字符串:"+json);
        //写入数据
        stringRedisTemplate.opsForValue().set("user:002",json);
        //获取数据
        String jsonUser = stringRedisTemplate.opsForValue().get("user:002");
        //反序列化
        User user = mapper.readValue(jsonUser, User.class);
        System.out.println("反序列化得到的结果:"+user);
    }
}

可以看到,里面是没有对象的字节码的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值