• 基础Redis-Java客户端操作介绍


    2.基础-Redis的Java客户端

    a.介绍

    在这里插入图片描述

    Jedis

    • 以Redis命令作为方法名称,学习成本低,简单实用。但是Jedis实例是线程不安全的,多线程环境下需要基于连接池来使用

    letture

    • Lettuce是基于Netty实现的,支持同步、异步和响应式编程方式,并且是线程安全的。支持Redis的哨兵模式、集群模式和管道模式。

    Redisson

    • Redisson是一个基于Redis实现的分布式、可伸缩的Java数据结构集合。包含了诸如Map、Queue、Lock、 Semaphore、AtomicLong等强大功能

    b.Jedis

    1.引入依赖:

    <dependency>
        <groupId>redis.clientsgroupId>
        <artifactId>jedisartifactId>
        <version>3.7.0version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.建立连接

    private Jedis jedis;
    @BeforeEach
    void setUp() {
        // 1.建立连接
        jedis = new Jedis("127.0.0.1",6379);
        // 2.设置密码
        //jedis.auth("");
        // 3.选择库
        jedis.select(0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.关闭连接

    @AfterEach
    void teardown() {
        if (jedis != null) {
            jedis.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.String类型

    @Test
    void testString() {
        // 存入数据
        String result = jedis.set("name", "John");
        System.out.println("result = " + result);
    
        // 获取数据
        String name = jedis.get("name");
        System.out.println("name = " + name);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5.hash类型

    @Test
    void testHash() {
        // 插入hash数据
        jedis.hset("user:1", "name", "jack");
        jedis.hset("user:1", "age", "21");
    
        // 获取
        Map<String, String> map = jedis.hgetAll("user:1");
        System.out.println(map);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    6.List类型

    @Test
    void testList() {
        // 插入数据
        jedis.lpush("jedisList:1", "A", "B");
        jedis.rpush("jedisList:1", "C", "D");
    
        String lpop = jedis.lpop("jedisList:1");
        System.out.println("lpop = " + lpop); // B
    
        String rpop = jedis.rpop("jedisList:1");
        System.out.println("rpop = " + rpop); // D
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    7.Set类型

    @Test
    void testSet() {
        // 插入数据
        jedis.sadd("zhangsan", "lisi", "wangwu", "zhaoliu");
    
        // 返回元素的个数
        Long scard = jedis.scard("zhangsan");
        System.out.println("scard = " + scard);
    
        // 获取所有元素
        Set<String> smembers = jedis.smembers("zhangsan");
        System.out.println("smembers = " + smembers);
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    8.SorterSet类型

    @Test
    void testSortedSet() {
        // 插入数据
        jedis.zadd("stuScore", 85, "Jack");
    
        // 获取
        Double zscore = jedis.zscore("stuScore", "Jack");
        System.out.println("zscore = " + zscore);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    c.Jedis连接池

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

    创建连接池 JedisPool

    public class JedisConnectionFactory {
        private static final JedisPool jedisPool;
    
        static {
            // 配置连接池
            JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
            // 最大连接数
            jedisPoolConfig.setMaxTotal(8);
            // 最大空闲连接
            jedisPoolConfig.setMaxIdle(8);
            // 最小空闲连接
            jedisPoolConfig.setMinIdle(0);
            // 等待时长
            jedisPoolConfig.setMaxWaitMillis(1000);
            // 创建连接池对象
            jedisPool = new JedisPool(jedisPoolConfig, 
                    "127.0.0.1", 6379, 1000);
        }
        
        public static Jedis getJedis() {
            return jedisPool.getResource();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    d.SpringDataRedis

    SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:https://spring.io/projects/spring-data-redis

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

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

    API返回值类型说明
    redisTemplate.opsForValue()ValueOperations操作String类型数据
    redisTemplate.opsForHash()HashOperations操作Hash类型数据
    redisTemplate.opsForList()ListOperations操作List类型数据
    redisTemplate.opsForSet()SetOperations操作Set类型数据
    redisTemplate.opsForZSet()ZSetOperations操作SortedSet类型数据
    redisTemplate通用的命令

    1.引入依赖

    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-data-redisartifactId>
    dependency>
    
    
    <dependency>
        <groupId>org.apache.commonsgroupId>
        <artifactId>commons-pool2artifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.配置文件

    • 默认使用lettuce的连接池
    spring:
      redis:
        host: 127.0.0.1
        port: 6319
        database: 0
        lettuce:
          pool:
            max-active: 8
            max-idle: 8
            min-idle: 0
            max-wait: 100ms
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3.注入RedisTemplate

    @Autowired
    private RedisTemplate redisTemplate;
    
    • 1
    • 2

    4.编写测试

    @Test
    void testString() {
        // 写入一条数据
        redisTemplate.opsForValue().set("name", "谷歌");
        // 获取string数据
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    e.SpringDataRedis的序列化方式

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

    在这里插入图片描述

    缺点:

    • 可读性差内存

    • 占用较大

    可以自定义RedisTemplate的序列化方式,代码如下:

    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
            // 创建RedisTemplate对象
            RedisTemplate<String, Object> template = new RedisTemplate<>();
    
            // 创建连接工厂
            template.setConnectionFactory(connectionFactory);
    
            // 创建JSON序列化工具
            GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
    
            // 设置key的序列化
            template.setKeySerializer(RedisSerializer.string());
            template.setHashKeySerializer(RedisSerializer.string());
    
            // 设置value的序列化
            template.setValueSerializer(jsonRedisSerializer);
            template.setHashValueSerializer(jsonRedisSerializer);
    
            // 返回
            return template;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    因为在自定义配置设置了RedisTemplate

    所以在自动注入时也需要指定RedisTemplate

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Test
    void testString() {
        // 写入一条数据
        redisTemplate.opsForValue().set("name", "谷歌");
        // 获取string数据
        Object name = redisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);
    }
    
    @Test
    void testSaveUser() {
        redisTemplate.opsForValue().set("user:100", new User("谷歌", 21));
        User user = (User) redisTemplate.opsForValue().get("user:100");
        System.out.println("user = " + user);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    f.StringRedisTemplate

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

    在这里插入图片描述

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

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    
    @Test
    void testString() {
        // 写入数据
        stringRedisTemplate.opsForValue().set("name", "百度");
    
        // 获取数据
        String name = stringRedisTemplate.opsForValue().get("name");
        System.out.println("name = " + name);
    }
    
    private static final ObjectMapper mapper = new ObjectMapper();
    
    @Test
    void testSaveUser() throws JsonProcessingException {
        // 创建对象
        User user = new User("腾讯", 20);
        // 手动序列化
        String json = mapper.writeValueAsString(user);
        // 写入数据
        stringRedisTemplate.opsForValue().set("user:200", json);
    
        // 获取数据
        String jsonUser = stringRedisTemplate.opsForValue().get("user:200");
        // 手动反序列化
        User user1 = mapper.readValue(jsonUser, User.class);
        System.out.println("user1 = " + user1);
    }
    
    @Test
    void testHash() {
        stringRedisTemplate.opsForHash().put("user:400", "name", "张三");
        stringRedisTemplate.opsForHash().put("user:400", "age", "22");
    
        Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:400");
        System.out.println("entries = " + entries);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
  • 相关阅读:
    排序算法(1)之插入排序----直接插入排序和希尔排序
    高斯消元(Java实现)
    从0到1学SpringCloud——10 springboot集成redis缓存
    数据结构题目收录(二十四)
    Delphi FMX开发,如何将文件打包到程序中
    600+ 道 Java面试题及答案整理(建议收藏)
    数据挖掘与分析课程笔记(Chapter 20)
    分享 | 智慧水务建设方案
    【chatglm3】(4):如何设计一个知识库问答系统,参考智谱AI的知识库系统,
    K8S概念与架构
  • 原文地址:https://blog.csdn.net/weixin_46926189/article/details/134233103