Redis学习(二)

1.Jedis是Redis的一个Java语言客户端连接工具(想要用Java去操作/使用Redis需要一个连接Redis的客户端,Jedis就是这个客户端,另外还有Lettuce、Redisson)。

引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
   	<groupId>redis.clients</groupId>
   	<artifactId>jedis</artifactId>
   	<version>2.9.0</version>
</dependency>

2.“Jedis线程不安全,会造成性能损耗,因此用连接池代替”

Q1:如何造成损耗?

Q2:怎么使用连接池?

A1:创建和销毁连接的开销巨大

A2:

public class JedisPoolExample {
    private static JedisPool jedisPool;

    public static void initPool() {
        // 配置连接池
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(128); // 最大连接数
        poolConfig.setMaxIdle(64);   // 最大空闲连接数
        poolConfig.setMinIdle(16);   // 最小空闲连接数
        poolConfig.setTestOnBorrow(true); // 获取连接时检查有效性
        poolConfig.setTestOnReturn(true); // 归还连接时检查有效性
        poolConfig.setTestWhileIdle(true); // 在空闲时检查连接有效性

        // 创建连接池
        // 参数依次为连接池配置、Redis服务器的主机名或IP、Redis服务器的端口、连接超时时间、密码(字符串)
        jedisPool = new JedisPool(poolConfig, "localhost", 6379, 10000, “123456”);
    }

    public static Jedis getJedis() {
        return jedisPool.getResource();
    }

    public static void closeJedis(Jedis jedis) {
        if (jedis != null) {
            // 归还连接到连接池
            jedis.close(); 
        }
    }
}

        Springboot项目中,在application.yml中配置Redis的连接信息合连接池参数。

spring:
  redis:
    host: localhost
    port: 6379
    password: 123456
    jedis:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 3000

3.Spring-Data-Redis

        相比Jedis,SpringDataRedis提供更高层次的抽象和整合,支持Spring框架。RedisTemplate是SpringDataRedis的一个工具类,可通过操作Redis。RedisTemplate封装了连接Redis、序列化、Redis 事务等操作。

3.1 引入依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

3.2 编写配置

        连接池Spring默认使用Lettuce,用Jedis要手动配。

server:
  port: 8081
spring:
  data:
    redis:
      #数据库索引
      database: 0
      #redis 服务器地址
      host: 127.0.0.1
      #redis 端口
      port: 6379
      #redis 密码 默认为空
      password:
      # 链接超时时间
      connect-timeout: 10s
      #lettuce连接池配置
      lettuce:
        pool:
          # 链接池中最小的空闲链接 默认为0
          min-idle: 0
          # 链接池中最大的空闲连接 默认为 8
          max-idle: 8
          #连接池中最大数据库链接数 默认为8
          max-active: 8
          #连接池最大阻塞等待时间 负值表示没有限制
          max-wait: 100ms

3.3 RedisTemplate

@Service
public class TestService {

    private final RedisTemplate<String, Object> redisTemplate;

    @Autowired
    public MyService(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
}

4.RedisTemplate序列化

        在将Java对象存储到Redis时,需要转化成字节数组,便于Redis能够正确存储和检索。这个转化的过程称作序列化。不同类型的数据(如字符串、列表、哈希等)在存储时需要统一的序列化方式,以确保数据在存取时能够被正确解析和还原。

        RedisTemplate接收任意Object前,会把Object序列化(默认JDK序列化)为字节形式。但是字节可读性差、存储成本高且序列化速度慢。

        因此自定义RedisTemplate的序列化方式来解决以上问题。Key用String类序列化,即使用StringRedisSerializer来将字符串进行序列化;Value或Hash用JSON序列化,即使用Jackson2JsonRedisSerializer来将Java对象序列化成JSON格式的字符串,这样可读性强。

@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){

    RedisTemplate<String,Object> template = new RedisTemplate<>();
    template.setConnectionFactory(connectionFactory);
    GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
    template.setKeySerializer(RedisSerializer.string());
    template.setHashKeySerializer(RedisSerializer.string());
    template.setValueSerializer(jsonRedisSerializer);
    template.setHashValueSerializer(jsonRedisSerializer);
    return template;
}

        但是,以上方法多用了class来帮助反序列化,多占用了空间。因此,可以试试统一用String序列化器,遇到Java对象则手动序列化和反序列化。

void testUser() throws JsonProcessingException {
    // 创建对象
    User user = new User("Alex",20);
    // 手动序列化
    String json = mapper.writeValueAsString(user);
    // 写入数据
    stringRedisTemplate.opsForValue().set("user:200",json);
    // 获取数据-默认获取的类型是json字符串
    String jsonUser = stringRedisTemplate.opsForValue().get("user:200");
    // 手动反序列化
    User user1 = mapper.readValue(jsonUser, User.class);
    System.out.println("user1 = "+user1);
}

        在项目中,可以将手动序列化和手动反序列化封装成一个工具类,直接调用即可了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值