Skip to content

Redis的JavaScript客户端 ​

前面我们讲解了Redis的常用命令,这些命令是我们操作Redis的基础,那么我们在java程序中应该如何操作Redis呢?这就需要使用Redis的Java客户端,就如同我们使用Mybatis操作MySQL数据库一样。

Redis 的 Java 客户端很多,常用的几种:

  • Jedis
  • Lettuce
  • Spring Data Redis

Spring生态中的Spring Data项目提供了统一的数据库操作框架,其中Spring Data Redis模块对Redis底层客户端进行了高度封装,显著简化了Redis数据库的开发和操作,这也是现在企业项目开发操作Redis的主流方式,因此我们重点学习Spring Data Redis。

Spring Data Redis的使用 ​

添加依赖 ​

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

Spring Data Redis中提供了一个高度封装的类:RedisTemplate,对相关api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:

  • ValueOperations:string数据操作
  • SetOperations:set类型数据操作
  • ZSetOperations:zset类型数据操作
  • HashOperations:hash类型的数据操作
  • ListOperations:list类型的数据操作

配置文件 ​

springboot项目中的redis配置参考如下:

yml
# Spring配置
spring:
  data:
    # redis 配置
    redis:
      # 地址
      host: 192.168.100.168
      # 端口,默认为6379
      port: 6379
      # 数据库索引
      database: 0
      # 密码
      password: 123456
      # 连接超时时间
      timeout: 10s
      lettuce:
        pool:
          # 连接池中的最小空闲连接
          min-idle: 0
          # 连接池中的最大空闲连接
          max-idle: 8
          # 连接池的最大数据库连接数
          max-active: 8
          # #连接池最大阻塞等待时间(使用负值表示没有限制)
          max-wait: -1ms

使用 ​

添加单元测试的依赖如下:

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

String的使用 ​

java
package com.xhzb.test;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;

import java.time.Duration;
import java.util.List;
import java.util.Map;

@SpringBootTest
public class RedisPractice {
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Test
    public void testString() {
        // set key value 设置指定 key 的值
        redisTemplate.opsForValue().set("name", "陈刚");
        // get key 获取指定 key 的值
        Object value = redisTemplate.opsForValue().get("name");
        System.out.println("get key获取到的值是:" + value); // get key获取到的值是:陈刚
        // mset key value [key value ...]  同时设置一个或多个 key-value 对
        redisTemplate.opsForValue().multiSet(Map.of("age", 18, "gender", "男", "height", 178));
        // mget key1 key2 ... 获取所有(一个或多个)给定 key 的值
        List<Object> values = redisTemplate.opsForValue().multiGet(List.of("age", "gender", "height"));
        System.out.println("mget key1 key2...批量获取到的值是:" + values); // mget key1 key2...批量获取到的值是:[18, 男, 178]
        // setnx key value 只有在 key 不存在时设置 key 的值,返回布尔值,false表示没有设置成功
        Boolean bool = redisTemplate.opsForValue().setIfAbsent("name", "王刚");
        System.out.println("setnx key value设置的结果是:" + bool); // setnx key value设置的结果是:false
        // incr key 将 key 中储存的数字值增一
        // incrby key increment 将 key 所储存的值加上给定的增量值(increment),如果不存在则默认设置为0然后再加上这个增量
        Long salary = redisTemplate.opsForValue().increment("salary");
        System.out.println("incrby key increment的结果是:" + salary); // incrby key increment的结果是:1
        // decr key 将 key 中储存的数字值减一
        Long distance = redisTemplate.opsForValue().decrement("distance");
        System.out.println("desr key的结果是:" + distance); // desr key的结果是:-1
        // decrby key decrement key 所储存的值减去给定的减量值(decrement)
        Long width = redisTemplate.opsForValue().decrement("width", 100);
        System.out.println(" decrby key decrement key的结果是:" + width); //  decrby key decrement key的结果是:-100
        // setex key seconds value 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)
        redisTemplate.opsForValue().set("info", "测试时间过去的数据", Duration.ofSeconds(10));
    }
}

Set的使用 ​

java
package com.xhzb.test;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Set;

@SpringBootTest
public class RedisPractice {
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Test
    public void testSet() {
        // sadd key member1 [member2] 向集合添加一个或多个成员
        redisTemplate.opsForSet().add("user_set_list1", "张三", "李四", "王五");
        redisTemplate.opsForSet().add("user_set_list2", "赵六", "李四", "何其");
        // smembers key 返回集合中的所有成员
        Set<Object> userSet1 = redisTemplate.opsForSet().members("user_set_list1");
        Set<Object> userSet2 = redisTemplate.opsForSet().members("user_set_list2");
        System.out.println("smembers key的结果是:" + userSet1); // smembers key的结果是:[张三, 李四, 王五]
        // scard key 获取集合的成员数
        Long size = redisTemplate.opsForSet().size("user_set_list1");
        System.out.println("scard key的结果是:" + size); // scard key的结果是:3
        // spop key 移除并返回集合中的一个随机元素
        Object value = redisTemplate.opsForSet().pop("user_set_list1");
        System.out.println("spop key的结果是:" + value); // spop key的结果是:张三
        // sinter key1 [key2] 返回给定所有集合的交集
        Set<Object> intersect = redisTemplate.opsForSet().intersect("user_set_list1", "user_set_list2");
        System.out.println("sinter key1 [key2]的结果是:" + intersect); // sinter key1 [key2]的结果是:[李四]
        // sunion key1 [key2] 返回所有给定集合的并集
        Set<Object> union = redisTemplate.opsForSet().union("user_set_list1", "user_set_list2");
        System.out.println("sunion key1 [key2]的结果是:" + union); // sunion key1 [key2]的结果是:[李四, 王五, 赵六, 何其]
        // sdiff key1 [key2] 返回给定所有集合的差集
        Set<Object> difference = redisTemplate.opsForSet().difference("user_set_list1", "user_set_list2");
        System.out.println("sdiff key1 [key2]的结果是:" + difference); // sdiff key1 [key2]的结果是:[王五]
        // srem key member1 [member2] 移除集合中一个或多个成员
        redisTemplate.opsForSet().remove("user_set_list1", "张三");
    }
}

Zset的使用 ​

// zadd key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
// zrange key start stop [withscores] 通过索引区间返回有序集合成指定区间内的成员,分数从底到高
// zrangebyscore key min max [withscores] [limit] 通过分数返回有序集合指定区间内的成员
// zrevrange key start stop [withscores] 返回有序集中指定区间内的成员,通过索引,分数从高到底
// zrevrangebyscore key max min [withscores] 返回有序集中指定分数区间内的成员,分数从高到低排序
// zincrby key increment member 有序集合中对指定成员的分数加上增量 increment
// zrem key member [member ...] 移除有序集合中的一个或多个成员
// zcard key 获取有序集合的成员数

Hash的使用 ​

java
package com.xhzb.test;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.List;
import java.util.Map;
import java.util.Set;

@SpringBootTest
public class RedisPractice {
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Test
    public void testHash() {
        // hset key field value 将哈希表 key 中的字段 field 的值设为 value
        redisTemplate.opsForHash().put("hash_test_user_info", "name", "chengang");
        // hget key field 获取存储在哈希表中指定字段的值
        Object name = redisTemplate.opsForHash().get("hash_test_user_info", "name");
        System.out.println("hget key field的结果是:" + name); // hget key field的结果是:chengang
        // hmset key field1 value1 [field2 value2 ] 同时将多个 field-value (域-值)对设置到哈希表 key 中
        redisTemplate.opsForHash().putAll("hash_test_user_info", Map.of("age", 31, "sex", "famale"));
        // hmget key field1 [field2] 获取所有给定字段的值
        List<Object> values = redisTemplate.opsForHash().multiGet("hash_test_user_info", List.of("name", "age", "gender"));
        System.out.println("hmget key field1 [field2]的结果是:" + values); // hmget key field1 [field2]的结果是:[chengang, 31, null]
        // hkeys key 获取所有哈希表中的字段
        Set<Object> keys = redisTemplate.opsForHash().keys("hash_test_user_info");
        System.out.println("hkeys key的结果是:" + keys); // hkeys key的结果是:[name, age, sex]
        // hvals key 获取哈希表中所有值
        List<Object> hashTestUserInfo = redisTemplate.opsForHash().values("hash_test_user_info");
        System.out.println(" hvals key的结果是:" + hashTestUserInfo); //  hvals key的结果是:[chengang, 31, famale]
        // hgetall key 获取在哈希表中指定 key 的所有字段和值
        Map<Object, Object> entries = redisTemplate.opsForHash().entries("hash_test_user_info");
        System.out.println("hgetall key的结果是:" + entries); // hgetall key的结果是:{name=chengang, age=31, sex=famale}
        // hdel key field2 [field2] 删除一个或多个哈希表字段
        redisTemplate.opsForHash().delete("hash_test_user_info", "gender", "age");
    }
}

List的使用 ​

java
package com.xhzb.test;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.List;

@SpringBootTest
public class RedisPractice {
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Test
    public void testHash() {
        // LPUSH KEY_NAME VALUE1.. VALUEN 将一个或多个值插入到列表头部
        // 从左边增加多个
        redisTemplate.opsForList().leftPushAll("test_user_list", "张三", "李四", "王五");
        // 增加一个
        redisTemplate.opsForList().leftPush("test_user_list", "赵六");
        // LRANGE KEY_NAME START END 返回列表中指定区间内的元素,区间以偏移量 START 和 END 指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。
        // 包含开始和结束吗,如果开始是0,结束是-1则表示拿到全部的
        List<Object> testUserList = redisTemplate.opsForList().range("test_user_list", 0, 3);
        System.out.println("输出的结果是:" + testUserList); // 输出的结果是:[赵六, 王五, 李四, 张三]
        // RPOP KEY_NAME Redis Rpop 命令用于移除并返回列表的最后一个元素
        Object rightPop = redisTemplate.opsForList().rightPop("test_user_list");
        System.out.println("rightPop的结果是:" + rightPop); // rightPop的结果是:张三
        Object leftPop = redisTemplate.opsForList().leftPop("test_user_list");
        System.out.println("leftPop的结果是:" + leftPop); // leftPop的结果是:赵六
    }
}