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的结果是:赵六
}
}