pom.xml
配置文件内容org.springframework.boot spring-boot-starter-parent 2.2.4.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-devtools true org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2 org.springframework.boot spring-boot-starter-test test
application.properties
与jedis的差别在于 将jedis改成了 lettuce
spring.redis.jedis.pool.xxx —> spring.redis.lettuce.pool.
lettuce 是线程安全的,多个线程之间共享一个连接池
哨兵模式 支持
redis.lettuce.xx redis.lettuce.xx 支持哨兵模式
############################【Redis】######################### # Redis数据库索引(默认为0) spring.redis.database=1 # Redis服务器地址 spring.redis.host=127.0.0.1 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password=root # 连接超时时间(毫秒) spring.redis.timeout=5000ms # 最大连接数,默认8 spring.redis.lettuce.pool.max-active=1024 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.lettuce.pool.max-wait=5000ms # 连接池中的最小空闲连接 spring.redis.lettuce.pool.min-idle=5 # 最大空闲连接数(使用负值表示没有限制) spring.redis.lettuce.pool.max-idle=200 ########### Redis集群的配置 ########### #spring.redis.cluster.nodes=127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381 #spring.redis.cluster.max-redirects=5 ########### 哨兵配置(注:jedis的不支持) ########### # 哨兵模式 主节点的名称 #spring.redis.sentinel.master=mymaster # 配置节点 IP:节点端口,IP:节点端口,IP:节点端口 #spring.redis.sentinel.nodes=127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381RedisTemplate模板注意事项
在使用redis的模板时注意,如果使用 RedisTemplate
类型时,@Autowired注解会报错 RedisTemplate
使用 @Autowired 会报错 这里需要使用 @Resource 注解
@Resource private RedisTemplate redisTemplate; //可以正常使用 @Resource private RedisTemplate序列化配置类redis; //可以正常使用 //@Autowired //private RedisTemplate template; //会提示报错,找不到对应的类 @Autowired private RedisTemplate template; //可以正常使用
RedisConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate redisTemplate(LettuceConnectionFactory lcf) {
RedisTemplate restTemplate = new RedisTemplate();
// 为String类型的key设置序列化
restTemplate.setKeySerializer(new StringRedisSerializer());
// 为String类型的value设置序列化
restTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// 为Hash类型的key设置序列化
restTemplate.setHashKeySerializer(new StringRedisSerializer());
// 为Hash类型的value设置序列化
restTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
restTemplate.setConnectionFactory(lcf);
return restTemplate;
}
}
测试Redis序列化
AppApplicationTests.java
@Test
public void testRedisConfig(){
User user = new User(1, "陌路", "1234567890", "1qaz2wsx3edc", "CD12345", new Date());
redisTemplate.opsForValue().set("user", user);
Object userVal = redisTemplate.opsForValue().get("user");
System.out.println("userVal = " + userVal);
}
操作字符串类型
@Test
public void testString(){
ValueOperations ops = redisTemplate.opsForValue();
// 添加一条数据
ops.set("redisKey", "redisVal");
// 获取单条数据
String rVal = ops.get("redisKey").toString();
System.out.println("rVal = " + rVal);
// 层级目录,目录形式存储数据
ops.set("molu:name", "陌路");
// 获取层级目录值
String str = ops.get("molu:name").toString();
System.out.println("str = " + str);
// 添加多条数据
Map map = new HashMap<>();
map.put("name", "陌路");
map.put("age", 25);
ops.multiSet(map);
// 获取多条数据
List keys = new ArrayList<>();
keys.add("name"); // 需要获取的key
keys.add("age"); // 需要获取的key
// 通过key集合获取对应的值
List list = ops.multiGet(keys);
list.forEach(System.out::println);
// 删除数据
Boolean isDel = redisTemplate.delete("redisKey");
System.out.println("isDel = " + isDel);
}
操作Hash类型
添加单条数据 redisKey hashKey val
put("redisKey", "hashKey", user) redisKey hashKey 数据值
get("redisKey", "hashKey"); redisKey hashKey
添加多条数据 redisKey map数据值
opsForHash.putAll("redisKeys", map); redisKey map集合类型的数值
获取多条数据 redisKey list类型的key集合
opsForHash.multiGet("redisKeys", kyes); redisKey list类型的key集合
取hash类型中所有数据 redisKey
opsForHash.entries("redisKeys"); redisKey 得到Map集合
entries.entrySet().forEach(item -> {String k = item.getKey()});
删除数据 返回删除的条数 redisKey hashKey …
opsForHash.delete("redisKeys", "name", "age"); redisKey hashKey …可以是多个hashKey
@Test
public void testHash() {
HashOperations opsForHash = redisTemplate.opsForHash();
// 添加单条数据 redisKey hashKey val
opsForHash.put("redisKey", "hashKey", user);
// 获取单条数据
Object objVal = opsForHash.get("redisKey", "hashKey");
System.out.println("objVal = " + objVal);
// 添加多条数据
Map map = new HashMap<>();
map.put("name", "陌路");
map.put("age", 25);
map.put("gender", "男");
opsForHash.putAll("redisKeys", map);
// 获取多条数据
List kyes = new ArrayList();
kyes.add("name");
kyes.add("gender");
// 获取多条数据 redisKey key集合
List list = opsForHash.multiGet("redisKeys", kyes);
list.forEach(System.out::println);
// 获取hash类型中所有数据
Map entries = opsForHash.entries("redisKeys");
entries.entrySet().forEach(item -> {
System.out.println("ksy = " + item.getKey() + " " + "value=" + item.getValue())
});
// 删除数据 返回删除的条数
Long del = opsForHash.delete("redisKeys", "name", "age");
System.out.println("del = " + del);
}
操作List集合
@Test
public void testList(){
ListOperations forList = redisTemplate.opsForList();
// 左添加
forList.leftPush("redisKey", "张三");
forList.leftPush("redisKey", "李四");
// 左添加 第三个参数会被添加到第二个参数的左边
forList.leftPush("redisKey", "李四", "周八");
// 右添加
forList.rightPush("redisKey", "王五");
forList.rightPush("redisKey", "赵六");
// 右添加 第三个参数会被添加到第二个参数的右边
forList.rightPush("redisKey", "赵六", "初九");
// 获取数据 开始索引 -1表示获取全部
List list = forList.range("redisKey", 0, -1);
list.forEach(System.out::println);
// 获取总条数
Long size = forList.size("redisKey");
System.out.println("size = " + size);
// 删除数据 redisKey 删除数量 删除的值 返回值为删除的条数
Long rem = forList.remove("redisKey", 1, "王五");
System.out.println("rem = " + rem);
// 左弹出 (删除左边的第一条数据) 返回值为弹出的值
Object leftPop = forList.leftPop("redisKey");
System.out.println("leftPop = " + leftPop);
// 右弹出 (删除右边的第一条数据) 返回值为弹出的值
Object rightPop = forList.rightPop("redisKey");
System.out.println("rightPop = " + rightPop);
}
操作set集合
添加数据 redisKey obj
forSet.add("redisKeyArr", new String[]{"aaa", "bbb"}); redisKey obj
forSet.add("redisKey", "eee", "fff", "ggg", "hhh"); redisKey obj
获取数据 redisKey
forSet.members("redisKeyArr"); redisKey 得到set集合
删除数据 redisKey val val … 返回删除条数
forSet.remove("redisKey", "ggg", "fff"); redisKey 删除的值 删除的值 返回删除条数
@Test
public void testSet() {
SetOperations forSet = redisTemplate.opsForSet();
// 添加数据 redisKey obj
String[] letters = new String[]{"aaa", "bbb", "ccc", "ddd"};
forSet.add("redisKeyArr", letters);
// 添加数据 redisKey val val val
forSet.add("redisKey", "eee", "fff", "ggg", "hhh");
// 获取数据 redisKey
Set setArr = forSet.members("redisKeyArr");
setArr.forEach(System.out::println);
Set setStr = forSet.members("redisKey");
setStr.forEach(System.out::println);
// 删除数据 redisKey val val ... 返回删除条数
Long remove = forSet.remove("redisKey", "ggg", "fff");
System.out.println("remove = " + remove);
// 删除数据 redisKey val val ... 返回删除条数
Long remove1 = forSet.remove("redisKeyArr", "ddd", "bbb");
System.out.println("remove1 = " + remove1);
}
操作zSet类型
添加数据 redisKey set类型Val
forZSet.add("score", tupleSet); redisKey set类型Val
获取数据 redisKey 0 startIndex endIndex -1 表示全部
forZSet.range("score", 0, -1); redisKey 0 startIndex endIndex -1 表示全部
range();返回的数据是根据 double数值排序后的结果值
添加数据 redisKey val值 double数值
forZSet.add("score", "周八", 99D); redisKey value值 double值
获取总条数 redisKey
forZSet.size("score"); redisKey
删除数据 返回删除的条数
forZSet.remove("score", "周八", "田七"); redisKey 要删除的val 要删除得到val
@Test
public void testSortedSet(){
ZSetOperations forZSet = redisTemplate.opsForZSet();
// 添加数据
ZSetOperations.TypedTuple
获取所有的key
获取所有的key
redisTemplate.keys("*"); * 表示获取所有(仅获取当前库中所有的key)
Redis数据库索引(默认为0)spring.redis.database = 1 配置文件中配置的库为当前库(不配默认0库)
@Test
public void testKeys(){
// * 表示获取当前库中的所有key
Set keys = redisTemplate.keys("*");
keys.forEach(System.out::println);
}
设置失效时间
添加key的时候设置有效时间
forValue.set("code", "0000", 50, TimeUnit.SECONDS); redisKey val值 失效时间 单位(ms、s、m、h、day…)
给已经存在的key设置失效时间
redisTemplate.expire("redisKey", 50, TimeUnit.SECONDS); redisKey 失效时间 单位
获取失效时间
redisTemplate.getExpire("code"); rediskey
@Test
public void testExpire(){
ValueOperations forValue = redisTemplate.opsForValue();
// 方法一,添加key的时候设置有效时间
forValue.set("code", "0000", 50, TimeUnit.SECONDS);
// 方法二,给已经存在的key设置失效时间
redisTemplate.expire("redisKey", 50, TimeUnit.SECONDS);
// 获取失效时间
Long timeout = redisTemplate.getExpire("code");
System.out.println("timeout = " + timeout);
}
哨兵模式配置
application.properties
# 哨兵模式 主节点的名称 spring.redis.sentinel.master=mymaster # 配置节点 IP:节点端口,IP:节点端口,IP:节点端口 spring.redis.sentinel.nodes=127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381哨兵的配置类
RedisConfig.java
@Bean
public RedisSentinelConfiguration redisSentinelConfiguration(){
RedisSentinelConfiguration rsconf = new RedisSentinelConfiguration()
// 主节点名称
.master("mymaster")
// 哨兵的配置
.sentinel("127.0.0.1", 26379)
.sentinel("127.0.0.1", 26380)
.sentinel("127.0.0.1", 26381);
rsconf.setPassword("root");
return rsconf;
}
Redis相关配置及所有示例
配置文件
哨兵模式 支持哨兵
spring.redis.lettuce.xxx redis.lettuce.xx 的支持哨兵模式 jedis.xx不支持
application.properties
############################【Redis】######################### # Redis数据库索引(默认为0) spring.redis.database=1 # Redis服务器地址 spring.redis.host=127.0.0.1 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password=root # 连接超时时间(毫秒) spring.redis.timeout=5000ms # 最大连接数,默认8 spring.redis.lettuce.pool.max-active=1024 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.lettuce.pool.max-wait=5000ms # 连接池中的最小空闲连接 spring.redis.lettuce.pool.min-idle=5 # 最大空闲连接数(使用负值表示没有限制) spring.redis.lettuce.pool.max-idle=200 ########### Redis集群的配置 ########### #spring.redis.cluster.nodes=127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381 #spring.redis.cluster.max-redirects=5 ########### 哨兵配置(注:jedis的不支持) ########### # 哨兵模式 主节点的名称 #spring.redis.sentinel.master=mymaster # 配置节点 IP:节点端口,IP:节点端口,IP:节点端口 #spring.redis.sentinel.nodes=127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381
序列化配置类
RedisConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate redisTemplate(LettuceConnectionFactory lcf) {
RedisTemplate restTemplate = new RedisTemplate();
// 为String类型的key设置序列化
restTemplate.setKeySerializer(new StringRedisSerializer());
// 为String类型的value设置序列化
restTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// 为Hash类型的key设置序列化
restTemplate.setHashKeySerializer(new StringRedisSerializer());
// 为Hash类型的value设置序列化
restTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
restTemplate.setConnectionFactory(lcf);
return restTemplate;
}
}
Redis示例代码
AppApplicationTests.java
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.*;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
@SpringBootTest
@RunWith(SpringRunner.class)
public class AppApplicationTests {
@Resource
private RedisTemplate redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
User user = new User(1, "陌路", "1234567890", "1qaz2wsx3edc", "CD12345", new Date());
@Test
public void testRedisConfig() {
redisTemplate.opsForValue().set("user", user);
Object userVal = redisTemplate.opsForValue().get("user");
System.out.println("userVal = " + userVal);
}
@Test
public void testString() {
ValueOperations ops = redisTemplate.opsForValue();
// 添加一条数据
ops.set("redisKey", "redisVal");
// 获取单条数据
String rVal = ops.get("redisKey").toString();
System.out.println("rVal = " + rVal);
// 层级目录,目录形式存储数据
ops.set("molu:name", "陌路");
// 获取层级目录值
String str = ops.get("molu:name").toString();
System.out.println("str = " + str);
// 添加多条数据
Map map = new HashMap<>();
map.put("name", "陌路");
map.put("age", 25);
ops.multiSet(map);
// 获取多条数据
List keys = new ArrayList<>();
keys.add("name"); // 需要获取的key
keys.add("age"); // 需要获取的key
// 通过key集合获取对应的值
List list = ops.multiGet(keys);
list.forEach(System.out::println);
// 删除数据
Boolean isDel = redisTemplate.delete("redisKey");
System.out.println("isDel = " + isDel);
}
@Test
public void testHash() {
HashOperations opsForHash = redisTemplate.opsForHash();
// 添加单条数据 redisKey hashKey val
opsForHash.put("redisKey", "hashKey", user);
// 获取单条数据
Object objVal = opsForHash.get("redisKey", "hashKey");
System.out.println("objVal = " + objVal);
// 添加多条数据
Map map = new HashMap<>();
map.put("name", "陌路");
map.put("age", 25);
map.put("gender", "男");
opsForHash.putAll("redisKeys", map);
// 获取多条数据
List kyes = new ArrayList();
kyes.add("name");
kyes.add("gender");
// 获取多条数据 redisKey key集合
List list = opsForHash.multiGet("redisKeys", kyes);
list.forEach(System.out::println);
// 获取hash类型中所有数据
Map entries = opsForHash.entries("redisKeys");
entries.entrySet().forEach(item -> {
System.out.println("ksy = " + item.getKey() + " " + "value=" + item.getValue());
});
// 删除数据 返回删除的条数
Long del = opsForHash.delete("redisKeys", "name", "age");
System.out.println("del = " + del);
}
@Test
public void testList(){
ListOperations forList = redisTemplate.opsForList();
// 左添加
forList.leftPush("redisKey", "张三");
forList.leftPush("redisKey", "李四");
// 左添加 第三个参数会被添加到第二个参数的左边
forList.leftPush("redisKey", "李四", "周八");
// 右添加
forList.rightPush("redisKey", "王五");
forList.rightPush("redisKey", "赵六");
// 右添加 第三个参数会被添加到第二个参数的右边
forList.rightPush("redisKey", "赵六", "初九");
// 获取数据 开始索引 -1表示获取全部
List list = forList.range("redisKey", 0, -1);
list.forEach(System.out::println);
// 获取总条数
Long size = forList.size("redisKey");
System.out.println("size = " + size);
// 删除数据 redisKey 删除数量 删除的值 返回值为删除的条数
Long rem = forList.remove("redisKey", 1, "王五");
System.out.println("rem = " + rem);
// 左弹出 (删除左边的第一条数据) 返回值为弹出的值
Object leftPop = forList.leftPop("redisKey");
System.out.println("leftPop = " + leftPop);
// 右弹出 (删除右边的第一条数据) 返回值为弹出的值
Object rightPop = forList.rightPop("redisKey");
System.out.println("rightPop = " + rightPop);
}
@Test
public void testSet() {
SetOperations forSet = redisTemplate.opsForSet();
// 添加数据 redisKey obj
String[] letters = new String[]{"aaa", "bbb", "ccc", "ddd"};
forSet.add("redisKeyArr", letters);
// 添加数据 redisKey val val val
forSet.add("redisKey", "eee", "fff", "ggg", "hhh");
// 获取数据 redisKey
Set setArr = forSet.members("redisKeyArr");
setArr.forEach(System.out::println);
Set setStr = forSet.members("redisKey");
setStr.forEach(System.out::println);
// 删除数据 redisKey val val ... 返回删除条数
Long remove = forSet.remove("redisKey", "ggg", "fff");
System.out.println("remove = " + remove);
// 删除数据 redisKey val val ... 返回删除条数
Long remove1 = forSet.remove("redisKeyArr", "ddd", "bbb");
System.out.println("remove1 = " + remove1);
}
@Test
public void testSortedSet(){
ZSetOperations forZSet = redisTemplate.opsForZSet();
// 添加数据
ZSetOperations.TypedTuple obj1 = new DefaultTypedTuple<>("张三", 98D); //1 5
ZSetOperations.TypedTuple obj2 = new DefaultTypedTuple<>("李四", 88D); //4 2
ZSetOperations.TypedTuple obj3 = new DefaultTypedTuple<>("王五", 95D); //2 4
ZSetOperations.TypedTuple obj4 = new DefaultTypedTuple<>("赵六", 86D); //5 1
ZSetOperations.TypedTuple obj5 = new DefaultTypedTuple<>("田七", 89D); //3
Set> tupleSet = new HashSet<>();
tupleSet.add(obj1);
tupleSet.add(obj2);
tupleSet.add(obj3);
tupleSet.add(obj4);
tupleSet.add(obj5);
// 添加 Set> 类型数据 redisKey set类型Val
forZSet.add("score", tupleSet);
// 获取数据 redisKey 0 startIndex endIndex -1 表示全部
Set scoreZet = forZSet.range("score", 0, -1);
scoreZet.forEach(System.out::println);
// 添加数据 redisKey val值 double数值
forZSet.add("score", "周八", 99D);
// 获取总条数 redisKey
Long size = forZSet.size("score");
System.out.println("size = " + size);
// 删除数据 返回删除的条数
Long remove = forZSet.remove("score", "周八", "田七");
System.out.println("remove = " + remove);
}
@Test
public void testKeys(){
Set keys = redisTemplate.keys("*");
keys.forEach(System.out::println);
}
@Test
public void testExpire(){
ValueOperations forValue = redisTemplate.opsForValue();
// 方法一,添加key的时候设置有效时间
forValue.set("code", "0000", 50, TimeUnit.SECONDS);
// 方法二,给已经存在的key设置失效时间
redisTemplate.expire("redisKey", 50, TimeUnit.SECONDS);
// 获取失效时间
Long timeout = redisTemplate.getExpire("code");
System.out.println("timeout = " + timeout);
}
}
redis的读写分离:https://blog.csdn.net/qq_51076413/article/details/123462448
docker拉取Redis:https://blog.csdn.net/qq_51076413/article/details/123462701
Java整合Jedis:https://blog.csdn.net/qq_51076413/article/details/123462857


