• redis 的java客户端 基础(一)


    目录

    一、redis的客户端语言支持

     二、Jedis快速入门

    2.1 Jedis连接池

    2.1.1 创建Jedis的连接池

     三、SpringDataRedis

     3.1 快速入门SpringDataRedis


    一、redis的客户端语言支持

    在Redis官网中提供了各种语言的客户端,地址:https://redis.io/resources/clients/

     其中Java客户端也包含很多:

    标记为❤的就是推荐使用的java客户端,包括:

    • Jedis和Lettuce:这两个主要是提供了Redis命令对应的API,方便我们操作Redis,而SpringDataRedis又对这两种做了抽象和封装,因此我们后期会直接以SpringDataRedis来学习。

    • Redisson:是在Redis基础上实现了分布式的可伸缩的java数据结构,例如Map.Queue等,而且支持跨进程的同步机制:Lock.Semaphore等待,比较适合用来实现特殊的功能需求。

     二、Jedis快速入门

    创建有个工程,引入依赖

    1. <dependency>
    2. <groupId>redis.clientsgroupId>
    3. <artifactId>jedisartifactId>
    4. <version>3.7.0version>
    5. dependency>
    6. <dependency>
    7. <groupId>org.junit.jupitergroupId>
    8. <artifactId>junit-jupiterartifactId>
    9. <version>5.7.0version>
    10. <scope>testscope>
    11. dependency>

    编写测试类: 

    1. public class JedisTest {
    2. private Jedis jedis;
    3. @BeforeEach
    4. void setUp(){
    5. //1、建立连接
    6. jedis= new Jedis("192.168.178.130",6379);
    7. //2、设置密码
    8. jedis.auth("123456");
    9. //3、选择库
    10. jedis.select(2);
    11. }
    12. @Test
    13. public void test(){
    14. //存入数据 ctrl+alt+v快速补全
    15. String result = jedis.set("name", "diaolovetest");
    16. System.out.println("result = " + result);
    17. String name = jedis.get("name");
    18. System.out.println(name);
    19. }
    20. @Test
    21. void testHash() {
    22. // 插入hash数据
    23. jedis.hset("user:1", "name", "Jack");
    24. jedis.hset("user:1", "age", "21");
    25. // 获取
    26. Map map = jedis.hgetAll("user:1");
    27. System.out.println(map);
    28. }
    29. @AfterEach
    30. void tearDown() {
    31. if (jedis != null) {
    32. jedis.close();
    33. }
    34. }
    35. }

    2.1 Jedis连接池

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

    有关池化思想,并不仅仅是这里会使用,很多地方都有,比如说我们的数据库连接池,比如我们tomcat中的线程池,这些都是池化思想的体现。

    2.1.1 创建Jedis的连接池

    • 使用工厂设计模式,去降低代的耦合,比如Spring中的Bean的创建,就用到了工厂设计模式

    • 2)静态代码块:随着类的加载而加载,确保只能执行一次,我们在加载当前工厂类的时候,就可以执行static的操作完成对 连接池的初始化

    • 3)最后提供返回连接池中连接的方法.

    1. package com.diao.util;
    2. import redis.clients.jedis.Jedis;
    3. import redis.clients.jedis.JedisPool;
    4. import redis.clients.jedis.JedisPoolConfig;
    5. /**
    6. * @Description: jedis连接池$
    7. * @Author: dyq
    8. * @Date: 2022年11月24日23:35:43$
    9. */
    10. public class JedisConnectionFacotry {
    11. private static final JedisPool jedisPool;
    12. static {
    13. //配置连接池
    14. JedisPoolConfig poolConfig = new JedisPoolConfig();
    15. poolConfig.setMaxTotal(8);//最大连接数
    16. poolConfig.setMaxIdle(8);//最大连接
    17. poolConfig.setMinIdle(0);//最小连接
    18. poolConfig.setMaxWaitMillis(1000);//最大连接时长
    19. //创建连接池对象
    20. jedisPool = new JedisPool(poolConfig,
    21. "192.168.178.130",6379,1000,"123456");
    22. }
    23. public static Jedis getJedis(){
    24. return jedisPool.getResource();
    25. }
    26. }

     三、SpringDataRedis

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

    • 提供了对不同Redis客户端的整合(Lettuce和Jedis)

    • 提供了RedisTemplate统一API来操作Redis

    • 支持Redis的发布订阅模型

    • 支持Redis哨兵和Redis集群

    • 支持基于Lettuce的响应式编程

    • 支持基于JDK.JSON.字符串.Spring对象的数据序列化及反序列化

    • 支持基于Redis的JDKCollection实现

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

     3.1 快速入门SpringDataRedis

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-data-redisartifactId>
    4. dependency>
    5. <dependency>
    6. <groupId>org.apache.commonsgroupId>
    7. <artifactId>commons-pool2artifactId>
    8. dependency>
    9. <dependency>
    10. <groupId>com.fasterxml.jackson.coregroupId>
    11. <artifactId>jackson-databindartifactId>
    12. dependency>
    13. <dependency>
    14. <groupId>org.projectlombokgroupId>
    15. <artifactId>lombokartifactId>
    16. <optional>trueoptional>
    17. dependency>
    18. <dependency>
    19. <groupId>org.springframework.bootgroupId>
    20. <artifactId>spring-boot-starter-testartifactId>
    21. <scope>testscope>
    22. dependency>

    配置文件

    1. spring:
    2. redis:
    3. host: 192.168.178.130
    4. port: 6379
    5. password: 123456
    6. lettuce:
    7. pool:
    8. max-active: 8 #最大连接
    9. max-idle: 8 #最大空闲连接
    10. min-idle: 0 #最小空闲连接
    11. max-wait: 100ms #连接等待时间

    编写测试类RedisDemoApplicationTests

    1. package com.example.redis_demo;
    2. import org.junit.jupiter.api.Test;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.boot.test.context.SpringBootTest;
    5. import org.springframework.data.redis.core.RedisTemplate;
    6. @SpringBootTest
    7. class RedisDemoApplicationTests {
    8. @Autowired
    9. private RedisTemplate redisTemplate;
    10. @Test
    11. void testString() {
    12. // 写入一条String数据
    13. redisTemplate.opsForValue().set("name", "diaoge");
    14. // 获取string数据
    15. Object name = redisTemplate.opsForValue().get("name");
    16. System.out.println("name = " + name);
    17. }
    18. }

     运行成功

     查看客户端数据

     

     什么是反序列化?反序列化的过程,原理_kali_Ma的博客-CSDN博客_反序列化

    尽管JSON的序列化方式可以满足我们的需求,但依然存在一些问题,如图

     

    为了在反序列化时知道对象的类型,JSON序列化器会将类的class类型写入json结果中,存入Redis,会带来额外的内存开销。

    为了减少内存的消耗,我们可以采用手动序列化的方式,换句话说,就是不借助默认的序列化器,而是我们自己来控制序列化的动作,同时,我们只采用String的序列化器,这样,在存储value时,我们就不需要在内存中就不用多存储数据,从而节约我们的内存空间

     

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

    最后小总结:

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

    • 方案一:

      • 自定义RedisTemplate

      • 修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer

    • 方案二:

      • 使用StringRedisTemplate

      • 写入Redis时,手动把对象序列化为JSON

      • 读取Redis时,手动把读取到的JSON反序列化为对象

    Hash结构的序列化操作

    1. @Test
    2. public void testHash(){
    3. stringRedisTemplate.opsForHash().put("user:400", "name", "牛哥");
    4. stringRedisTemplate.opsForHash().put("user:400", "age", "22");
    5. Map entries = stringRedisTemplate.opsForHash().entries("user:400");
    6. System.out.println("entries = " + entries);
    7. }

    声明: 个人学习记录,不做商业用途,来源于B站黑马程序员redis!

  • 相关阅读:
    【算法与数据结构】77、LeetCode组合
    【刷题篇】反转链表
    EXTJS 中grid 动态增加列的方法
    基于prim算法的网络最小生成树生成得到路径规划
    寻路算法之A*算法详解
    Spring5 框架 ---- Spring5的新功能
    下列程序的运行结果是 #include <stdio.h> void main() { int x = 10, y = 20, z = 30;
    Pycharm 日常方便工具和快捷键
    【39. 最长公共子序列】
    静态链接库(Lib) 与 动态链接库(DLL)
  • 原文地址:https://blog.csdn.net/qq_45047809/article/details/128028742