前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis快速入门(三)

Redis快速入门(三)

作者头像
cheese
发布2023-10-25 11:23:23
1870
发布2023-10-25 11:23:23
举报
文章被收录于专栏:Java PorterJava Porter

一. Redis的Java客户端

image.png
image.png

二. Jedis

Jedis的官网地址:https://github.com/redis/jedis,通过一个最简单的Demo实现快速入门:

2.1.实现流程

代码语言:javascript
复制
<!--引入jedis-->
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>4.3.1</version>
</dependency>
<!--单元测试-->
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter</artifactId>
  <version>5.7.0</version>
  <scope>test</scope>
</dependency>
代码语言:javascript
复制
private Jedis jedis;
@BeforeEach
    void setUp(){
    //1.建立连接
    /*方式一直接创建*/
    //jedis = new Jedis("192.168.80.3", 6379);
    /*方式二使用连接池创建*/
    jedis = JedisConnectionFactory.getJedis();
    //2.设置密码
    jedis.auth("123456");
    //3.选库
    jedis.select(0);
}
代码语言:javascript
复制
    @Test
    void testString(){
        //存入数据
        String result = jedis.set("name", "lmj");
        System.out.println("result="+result);
        //读取数据
        String name = jedis.get("name");
        System.out.println("name="+name);
    }
代码语言:javascript
复制
    @AfterEach
    void tearDown(){
        if(jedis!=null){
            jedis.close();
        }
    }

查看运行结果

image.png
image.png

2.2. 小结——Jedis的使用基本步骤

  1. 引入依赖
  2. 创建Jedis对象,建立连接
  3. 使用Jedis,方法名与Redis命令一致
  4. 释放资源

2.3.Jedis连接池

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

代码语言:javascript
复制
public class JedisConnectionFactory {
    private static final 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.80.3",6379,1000,"123456");
    }
    public static Jedis getJedis(){
        return jedisPool.getResource();
    }
}

三.SpringDataRedis

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

3.1. 优点

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

3.2. 常用API

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:

image.png
image.png

3.3. 入门案例

SpringBoot已经提供了对SpringDataRedis的支持:

代码语言:javascript
复制
<!--引入redis依赖-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--引入common-pool-->
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-pool2</artifactId>
</dependency>

代码语言:javascript
复制
spring:
  redis:
    host: 192.168.80.3
    port: 6379
    password: 123456
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 100ms

代码语言:javascript
复制
@SpringBootTest
class JedisDemo2ApplicationTests {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Test
    void contextLoads() {
        redisTemplate.opsForValue().set("name","ljz");
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name="+name);
    }
}

image.png
image.png

3.4. 小结——SpringDataRedis的使用步骤:

1.引入spring-boot-starter-data-redis依赖 2.在application.yml配置Redis信息 3.注入RedisTemplate


3.5. SpringDataRedis的序列化方式

RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的:

image.png
image.png
  • 缺点:
    • 可读性差
    • 内存占用较大
  • 默认的JDK序列化源码解析
    • 关于序列化现象的解读
image.png
image.png
  1. RedisTemplate类默认作为集合泛型
  2. 存入的value值为中文字符
  3. 在程序运行前后分别对redis进行两次get name得到的结果并没有发生改变
  4. 通过keys *找到了JDK序列化得到的"小李"真正的键值对
  • Debug调试
image.png
image.png
  1. 进入set方法:
    1. value被rawValue()进行装饰
    2. 将结果由Java转化成字节
image.png
image.png
  1. 进入装饰器rawValue(),返回value的序列化值
image.png
image.png
  1. 进入到JdkSerializationRedisSerializer
image.png
image.png
image.png
image.png
  1. 最终将Java对象通过ObjectOutputStrem转化成字节数据
  • 使用自定义RedisTemplate的序列化方式
    • 关于RedisSerializer的实现类(选中+H查看接口/类的实现类)
image.png
image.png
代码语言:javascript
复制
  - JdkSerializationRedisSerializer(默认,不推荐使用)
  - StringRedisSerializer(专门用于处理字符串)
     -  字符串若想转字节存入Redis只需调用getBytes()即可
     - key或hashkey均为String时使用该实现
  - GenericJackson2JsonRedisSerializer(若value为对象时使用)
  • 小结
    • key用String
    • value用json

3.6. 自定义序列化

  • 引入Jackson依赖
代码语言:javascript
复制
<!--引入Jackson依赖-->
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
</dependency>
  • 编写配置类
代码语言:javascript
复制
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        //创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //设置连接工厂
        template.setConnectionFactory(redisConnectionFactory);
        //创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        //设置key的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        //设置value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(RedisSerializer.json());
        //返回
        return template;
    }
}
  • 测试结果
image.png
image.png

3.7. 自定义序列化Java对象

  • 引入lombok依赖
代码语言:javascript
复制
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <optional>true</optional>
</dependency>
  • 创建对象类Entity.User
代码语言:javascript
复制
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private int age;
}
  • 编写测试代码
代码语言:javascript
复制
	@Test
    void testSaveUser(){
        //写入数据
        redisTemplate.opsForValue().set("user:100",new User("小李",24));
        //获取数据
        User user = (User) redisTemplate.opsForValue().get("user:100");
        System.out.println("user="+user);
    }
  • 运行结果
image.png
image.png
  • 小结
    • 尽管JSON的序列化方式可以满足我们的需求,但依然存在一些问题,如运行结果:
    • 为了在反序列化时知道对象的类型,JSON序列化器会将类的class类型写入json结果中,存入Redis,会带来额外的内存开销。
  • StringRedisTemplate运行过程

为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。


image.png
image.png

Spring默认提供了一个StringRedisTemplate类,它的key和value的序列化方式默认就是String方式。省去自定义RedisTemplate的过程:

  • 直接使用StringRedisTemplate
代码语言:javascript
复制
private static final ObjectMapper mapper = new ObjectMapper();
	@Test
    void testSaveUser() throws JsonProcessingException {
        //创建对象
        User user = new User("小李", 24);
    	//手动序列化
    	String json = mapper.writeValueAsString(user);
    	//写入数据
    	stringRedisTemplate.opsForValue().set("user:200",json);
    	//获取数据
    	String json1 = stringRedisTemplate.opsForValue().get("user:200");
    	//手动反序列化
    	User user1 = mapper.readValue(json1, User.class);
    	System.out.println("user1="+user1);
	}
代码语言:javascript
复制
  - 运行结果
image.png
image.png
  • 操作Hash对象
代码语言:javascript
复制
@Test
    void testHash(){
        stringRedisTemplate.opsForHash().put("user:300","name","小李");
        stringRedisTemplate.opsForHash().put("user:300","age","24");

        Map<Object, Object> map = stringRedisTemplate.opsForHash().entries("user:300");
        System.out.println("map="+map);
    }
代码语言:javascript
复制
  - 运行结果
image.png
image.png

3.8. RedisTemplate的两种序列化实践方案:

方案一: 1.自定义RedisTemplate 2.修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer 方案二: 1.使用StringRedisTemplate 2.写入Redis时,手动把对象序列化为JSON 3.读取Redis时,手动把读取到的JSON反序列化为对象

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. Redis的Java客户端
  • 二. Jedis
    • 2.1.实现流程
      • 2.2. 小结——Jedis的使用基本步骤
        • 2.3.Jedis连接池
        • 三.SpringDataRedis
          • 3.1. 优点
            • 3.2. 常用API
              • 3.3. 入门案例
                • 3.4. 小结——SpringDataRedis的使用步骤:
                  • 3.5. SpringDataRedis的序列化方式
                    • 3.6. 自定义序列化
                      • 3.7. 自定义序列化Java对象
                        • 3.8. RedisTemplate的两种序列化实践方案:
                        相关产品与服务
                        云数据库 Redis
                        腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档