Redis连接池、SpringDataRedis和序列化器

个人Blog:dykang.top

Redis的Java 客户端

Jedis

引入依赖

<dependencies>
        <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>
        </dependency>
 </dependencies>

使用

private Jedis jedis;
​
//建立连接
@BeforeEach
void setUp(){
     jedis = new Jedis("localhost", 6379);
     jedis.select(0);
}
​
//存数据取数据
@Test
public void testString(){
    String se = jedis.set("k", "19");
    System.out.println("se = " + se);
    String s = jedis.get("k");
    System.out.println("s = " + s);
}
//关闭连接
@AfterEach
void closeCon(){
    if (jedis!=null)
    {
        jedis.close();
    }
}
Jedis的连接池
private static final JedisPool jedisPool;
​
static {
​
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    //最大连接数
    jedisPoolConfig.setMaxTotal(8);
    //最大空闲数 可以预备8个空闲连接,直接使用
    jedisPoolConfig.setMaxIdle(8);
    //最小空闲数
    jedisPoolConfig.setMinIdle(0);
    //最大等待时间  没有可用的jedis连接,等待这些时间之后就会报错
    jedisPoolConfig.setMaxWaitMillis(1000);
​
    jedisPool = new JedisPool(jedisPoolConfig,"localhost",6379);
}
​
//获取
public static Jedis getJedis(){
    Jedis jedis = jedisPool.getResource();
    return jedis;
}

利用连接池对象创建jedis,不需要关闭jedis资源,底层代码会自动将jedis连接放回连接池

public void close() {
        if (this.dataSource != null) {
            JedisPoolAbstract pool = this.dataSource;
            this.dataSource = null;
            if (this.isBroken()) {
                pool.returnBrokenResource(this);
            } else {
                pool.returnResource(this);
            }
        } else {
            super.close();
        }
    }

SpringDataRedis

介绍

特征:

封装的API

入门

引入依赖

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

commons-pool2 jedis 和lettuce底层都是pool连接池,所以需要引入连接池的依赖

配置yml

spring:
  redis:
    host: localhost
    database: 0
    port: 6379
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 1000ms

使用lettuce连接池,因为redis起步依赖引入的是lettuce依赖

注入RedisTemplate

    @Autowired
    private RedisTemplate redisTemplate;
​
    @Test
    void contextLoads() {
       redisTemplate.opsForValue().set("name","虎哥");
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);
    }
RedisSerializer

key推荐使用string类型

value推荐使用Json类型

/**
 * Redis序列化配置
 */
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){
        //创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //设置连接工厂
      template.setConnectionFactory(connectionFactory);
        //创建Json序列化工具
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        //设置Key的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
​
        //设置Value的序列化
        template.setValueSerializer(genericJackson2JsonRedisSerializer);
        template.setHashValueSerializer(genericJackson2JsonRedisSerializer);
​
        return template;
    }
}

有时候会需要加这个依赖

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>
GenericJackson2JsonRedisSerializer和Jackson2JsonRedisSerializer有什么区别?
  1. 泛型支持:

    • GenericJackson2JsonRedisSerializer 支持泛型,可以在序列化时保留对象的实际类型信息。这对于处理复杂的对象结构很有用,因为它可以确保在反序列化时正确地还原对象的类型。这个特性对于存储和检索具有继承关系的对象非常有用。(通过反射)

    • Jackson2JsonRedisSerializer 不支持泛型,它在反序列化时会将对象都转换为指定的目标类,因此在处理继承关系的对象时可能会失去类型信息。

  2. 默认构造函数:

    • GenericJackson2JsonRedisSerializer 需要提供要序列化和反序列化的类的引用作为构造函数的参数,因为它要确保能够正确地处理泛型类型。(必须加get set 无参有参构造方法)

    • Jackson2JsonRedisSerializer 则可以使用默认构造函数,只需要设置目标类即可,因为它不处理泛型。

在选择使用哪个取决于你的需求。如果你的对象结构相对简单,而且不需要在反序列化时保留实际类型信息,那么Jackson2JsonRedisSerializer 可能足够了。如果你的对象结构更复杂,包含了继承关系,并且需要在反序列化时保留实际类型信息,那么 GenericJackson2JsonRedisSerializer 可能更适合。

序列化:对象到JSON

反序列化:JSON到对象

StringRedisTemplate

因为Json序列化器会将原先的数据类型(类的字节码)同时保存到了redis中,占用redis的空间。因此我们将手动序列化,然后手动完成反序列化,不让原先的数据类型保存到redis中去占用空间

@Autowired
    private StringRedisTemplate stringRedisTemplate;
​
    //Spring提供的Json序列化反序列化工具
    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    @Test
    void testSaveUser() throws JsonProcessingException {
        User user = new User("kkk",19);
        //手动序列化
        String json = objectMapper.writeValueAsString(user);
        //存入redis
        stringRedisTemplate.opsForValue().set("user:info1",json);
​
        String user1 = stringRedisTemplate.opsForValue().get("user:info1");
        //手动反序列化成user对象
        User user2 = objectMapper.readValue(user1, User.class);
        System.out.println("user2 = " + user2);
    }
操作Hash
@Test
void testHash(){
    stringRedisTemplate.opsForHash().put("heima:200","name","kzy");
    stringRedisTemplate.opsForHash().put("heima:200","age",19);
​
    Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("heima:200");
    System.out.println("entries = " + entries);
}

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值