Spring Boot: 集成Redis 基本操作、事务、流水线、订阅、发布、序列化
源码
链接:https://pan.baidu.com/s/14C7BOcehDrbNsmH3Np44qQ
提取码:uaac
- 目录结构
- 添加依赖
- 配置redis数据源
- 实现
1.目录结构
- 添加依赖
点击查看代码
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 配置redis数据源
点击查看代码
#Redis 数据库索引(默认为0)
spring.redis.database=0
#Redis 服务器地址
spring.redis.host=localhost
#Redis 服务器连接端口
spring.redis.port=6379
#Redis 服务器连接密码(默认为空)
spring.redis.password=
#连接池最大连接数(使用负值表示没有限制)默认8
spring.redis.lettuce.pool.max-active=8
#连接池最大阻塞等待时间(使用负值表示灭有限制)默认-1
spring.redis.lettuce.pool.max-wait=-1
#连接池中的最大空闲连接 默认 8
spring.redis.lettuce.pool.max-idle=8
#连接池中最小空闲连接 默认 0
spring.redis.lettuce.pool.min-idle=0
- 实现
Controller类如下,内容较多没有截图, 请点击查看代码
点击查看代码
package com.yq.demo.controller;
import com.yq.demo.config.RedisConfig;
import com.yq.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisZSetCommands;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/redis")
public class TestRedisController {
@Autowired
private RedisTemplate redisTemplate;
/**
* redis存储key,value
* */
@GetMapping("/setValue")
public String setValue(String key,String strValue){
redisTemplate.opsForValue().set(key,strValue);
return "success";
}
/**
* 根据key读取redis的value值
* */
@GetMapping("/getValue")
public String getValue(String key){
return (String)redisTemplate.opsForValue().get(key);
}
/**
* 将对象存储到redis
* */
@GetMapping("/setUser")
public String setValue(String key,String userName,int age,String tel){
int userId=1;
User user=new User();
user.setUserId(userId);
user.setAge(age);
user.setUserName(userName);
user.setTel(tel);
// ValueOperations<String, User> operations=redisTemplate.opsForValue();
// operations.set(key,user);
// redisTemplate.opsForValue().set(key,user);
//参数100是过期时间,超过这个时间就会自动删除数据
redisTemplate.opsForValue().set(key,user,100, TimeUnit.MILLISECONDS);
return "success";
}
/**
* 根据key获取存储的对象数据
* */
@GetMapping("/getUser")
public String setValue(String key){
if(redisTemplate.hasKey(key)){
User user=(User)redisTemplate.opsForValue().get(key);
return user.toString();
}
return "null";
}
/**
* 删除数据
* */
@GetMapping("/delete")
public void delKey(String key){
if(redisTemplate.hasKey(key)){
redisTemplate.delete(key);
}
}
@GetMapping("/value")
public void value(){
String key="v1";
String key2="v2";
redisTemplate.delete(key);
//使用increment,append需要加上序列化
redisTemplate.setValueSerializer(new StringRedisSerializer());
ValueOperations<String, String> v1=redisTemplate.opsForValue();
v1.set(key,"13");
long l1=v1.increment(key);//value+1
long l2=v1.increment(key,100);//value+100
long l3=v1.decrement(key);//value-1
v1.set(key2,"a");
v1.append(key2,"bcdef");//value末尾追加字符串
System.out.println(v1.get(key2));
String str=v1.get(key2,1,2);//截取value从索引1到索引2,包含1,2
System.out.println(str);
v1.set(key2,"12",1);//从索引1开始字符串被替换,bc被12替换
System.out.println(v1.get(key2));
}
@GetMapping("/hash")
public void hash(){
//Charset.forName("ISO_8859_1")
redisTemplate.delete("user");
//下面有使用increment需要序列化
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
HashOperations<String,Object,Object> hash=redisTemplate.opsForHash();
hash.put("user","id","1");
hash.put("user","userName","Jack");
Set<Object> sets=hash.keys("user");//返回所有键,id,userName
System.out.println("keys:");
for(Object obj:sets){
System.out.println((String)obj);
}
List<Object> list=hash.values("user");
System.out.println("values:");
for(Object obj:list){
System.out.println(String.valueOf(obj));
}
hash.increment("user","id",10);//user-id的value值+10
System.out.println(hash.size("user"));
Map<Object, Object> map=hash.entries("user");
System.out.println("entries:");
for(Map.Entry<Object, Object> entry:map.entrySet()){
System.out.print("key:"+entry.getKey()+" ");
System.out.println("value:"+entry.getValue());
}
}
@GetMapping("/list")
public void testList(){
redisTemplate.delete("list");
ListOperations<String,String> list =redisTemplate.opsForList();
list.leftPush("list","hello");
list.leftPush("list","world");
List<String> values=list.range("list",0,1);
list.rightPush("list","hello");
long l1=list.rightPush("list","world");//返回元素总数
long l2=list.rightPush("list","777");
long l3=list.leftPush("list","888");
String str=list.index("list",1);//获取执行下标的元素
list.trim("list",1,3);//只保留下标1-3的元素,包含1和3
values=list.range("list",0,-1);//-1表示数组的结尾,获取所有元素
for(String val:values){
System.out.println(val);
}
String strV=list.leftPop("list");//移除最左端元素,返回被移除的元素
System.out.println(strV);
list.size("list");
//没有数据时会阻塞在这里,阻塞超时时间10s
list.leftPop("list",10,TimeUnit.SECONDS);
}
@GetMapping("/set")
public void set(){
redisTemplate.delete("userName");
redisTemplate.delete("name");
/*
* set会去掉重复项Jack
* */
SetOperations<String,String> set=redisTemplate.opsForSet();
set.add("userName","Jack");
set.add("userName","Jack");
set.add("userName","Jone");
Set<String> values=set.members("userName");
String strPop=set.pop("userName");//从集合中随机移除一个元素并返回这个元素
System.out.println("strPop:"+strPop);
set.add("name","Jack");
set.add("name","Tom");
//将userName集合中的Jone移动到集合name中,userName集合会删除Jone
if(set.move("userName","Jone","name")){
values=set.members("name");
System.out.println("name : ");
for(String val:values){
System.out.println("val : "+val);
}
}
values=set.members("userName");
if(values!=null && values.size()>0){
System.out.println("userName : ");
for(String val:values){
System.out.println("val : "+val);
}
}
//将userName中不同于name的数据找出来
values=set.difference("userName","name");
System.out.println("difference : ");
for(String val:values){
System.out.println("val : "+val);
}
//合并两个set
values=set.union("userName","name");
System.out.println("union : ");
for(String val:values){
System.out.println("val : "+val);
}
//检查元素是否存在于集合中
boolean b=set.isMember("userName","Jack");
//从集合中删除元素,返回删除的个数
long i=set.remove("userName","Jack","Jone");
}
@GetMapping("/zset")
public void zset(){
String key="zset";
redisTemplate.delete(key);
ZSetOperations<String,String> zset=redisTemplate.opsForZSet();
boolean b=zset.add(key,"hello",1);
b=zset.add(key,"world",4);
b=zset.add(key,"at",2);
b=zset.add(key,"at",2);//key-value-score相同时返回false
b=zset.add(key,"at1",2);//key-score相同新增的会向后增加
Double d=zset.incrementScore(key,"s1",2);//分值不变 排序在score=2之后递增
d=zset.incrementScore(key,"s2",2);//分值不变 排序在score=2之后递增
b=zset.add(key,"at2",2);//分值不变,相同分值排序会在incrementScore之后递增
long size=zset.size(key);//获取集合内元素总数
Set<String> values=zset.range(key,0,size);//获取指定下标范围内的元素,size也可用-1,-1表示集合末尾
for(String val:values){
System.out.println("val : "+val);//打印value
System.out.println(zset.score(key,val));//打印分值
}
values=zset.reverseRange(key,0,size);//反向排序
values=zset.rangeByScore(key,2,4);//获取分值在2-4之间的包含2和4
zset.count(key,2,4);//指定分值范围内集合内元素的数量
long index=zset.rank(key,"at2");//返回成员在集合中的排序,从1开始计数
System.out.println("index:"+index);
b=zset.add(key+"1","world",1);
b=zset.add(key+"1","at",5);
b=zset.add(key+"2","at-2",2);
//intersectAndStore取集合1和集合2的交接赋值到集合3中,如集合3元原有元素会被清除,返回交集元素个数
//新集合中元素的score等于集合1中元素的score+集合2中元素的scroe,默认使用Sum函数
//Aggregate可选函数有SUM,MIN, MAX;
Long aLong = redisTemplate.opsForZSet().intersectAndStore(key, key+"1",key+"2");
values=zset.reverseRange(key+"2",0,-1);
System.out.println("intersectAndStore:");
for(String val:values){
System.out.print("val : "+val+" score:");//打印value
System.out.println(zset.score(key+"2",val));//打印分值
}
System.out.println("");
List<String> keys=new ArrayList<>();
keys.add(key+"1");
keys.add(key+"2");
zset.intersectAndStore(key,keys,key+"3", RedisZSetCommands.Aggregate.MIN);//交集
}
/**
* 设置和取消键过期时间
* */
public void timeout(){
redisTemplate.persist("key");//移除键的过期时间
redisTemplate.expire("key",100,TimeUnit.SECONDS);//为键设置过期时间
redisTemplate.getExpire("key");//获取过期时间
}
/**
* Redis事务
* */
@GetMapping("/transaction")
public void transaction(){
redisTemplate.execute(new SessionCallback() {
@Override
public Object execute(RedisOperations redisOperations) throws DataAccessException {
redisOperations.watch("a1");
redisOperations.multi();
ValueOperations<String, String> valueOperations=redisOperations.opsForValue();
valueOperations.set("a1","abcd1234");
valueOperations.set("a2","a2cd");
List<Object> list=redisOperations.exec();
if(list!=null && list.size()>0){
for(Object obj:list){
if(obj instanceof Number){
System.out.println((long)obj);
}else{
System.out.println(String.valueOf(obj));
}
}
}
return "";
}
}
);
System.out.println("finished");
}
/**
* 流水线 耗时406毫秒
* */
@GetMapping("/pipeline")
public void pipeline(){
String key="key_pipeline";
redisTemplate.delete(key);
redisTemplate.executePipelined(new SessionCallback<String>() {
@Override
public String execute(RedisOperations operations) throws DataAccessException {
ListOperations<String, String> valueOperations=operations.opsForList();
System.out.println(new Date().getTime());
for(int i=0;i<20000;i++){
valueOperations.leftPush(key,String.valueOf(i));
}
System.out.println(new Date().getTime());
return null;
}
});
}
/**
* 非流水线耗时 1589毫秒
* */
@GetMapping("/pipeline_1")
public void pipeline_1(){
ListOperations<String, String> valueOperations=redisTemplate.opsForList();
String key="key_pipeline";
System.out.println(new Date().getTime());
for(int i=0;i<20000;i++){
valueOperations.leftPush(key,String.valueOf(i));
}
System.out.println(new Date().getTime());
}
/**
* 消息发布和订阅 -- 消息发送
* */
@GetMapping("/sendMessage")
public void sendMessage(){
//发送字符串
redisTemplate.convertAndSend(RedisConfig.channelTopic_02,"大强");
// //自定义序列化方式
// Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
// ObjectMapper objectMapper = new ObjectMapper();
// objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
//
// redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
// redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
// redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
// redisTemplate.afterPropertiesSet();
User user=new User();
user.setUserId(1);
user.setUserName("大于");
user.setAge(23);
user.setTel("18844445555");
//发送对象
redisTemplate.convertAndSend(RedisConfig.channelTopic_01,user);
}
/**
* 持久化说明
* redis持久化是在redis.windows.conf文件中配置的
* 持久化方式一:快照 SNAPSHOTTING
* 默认将数据存储在dump.rdb文件中
* save 900 1 ## 900秒之内有1次写入时redis自动触发bgsave
* save 300 10
* save 60 10000
* 以上只要有一个条件成立就会触发bgsave
*
* 持久化方式二:追加文件 APPEND ONLY MODE
* 默认将文件存储在.aof文件中
* 是将执行的写命令追加到AOF文件末尾,每次通过从头到尾重新执行一次AOF文件包含的所有写命令来恢复所记录的数据
* appendfsync always # 一直同步
* appendfsync everysec # 每秒同步 默认
* appendfsync no # 操作系统决定同步
* auto-aof-rewrite-percentage 100 #
* auto-aof-rewrite-min-size 64mb # AOF文件体积大于64MB且体积比上一次重写之后体积大了一倍的时候触发bgrewriteaof来压缩文件
*
* */
/**
* 主从复制
* 通过配置文件设置 slaveof <masterip> <masterport> 启动redis后开始同步
* 通过redisTemplate.slaveOf(String host,int port); 启动同步
* 同步过程:
* 简历连接->主创建bgsave快照->向从发送快照->主持续将bgsave之后执行的命令存入缓冲区
* ->从接收快照->从接收缓冲区命令并执行->执行主发过来的命令
* */
/**
* key存在返回false 不更新
* key不存在则创建
* */
@GetMapping("/absent")
public void absent(String key,String value){
if(redisTemplate.opsForValue().setIfAbsent(key,value)){
System.out.println("true");
}else{
System.out.println("false");
}
}
/**
* key存在则更新
* key不存在返回 false
* */
@GetMapping("/present")
public void present(String key,String value){
if(redisTemplate.opsForValue().setIfPresent(key,value)){
System.out.println("true");
}else{
System.out.println("false");
}
}
}
Config配置类 内容较多没有截图, 请点击查看代码
点击查看代码
package com.yq.demo.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
/**
* 配置消息
* @author:yuqiang
* @date:2022.2.9
* */
@Configuration
@EnableCaching
public class RedisConfig {
public static String channelTopic_01="channel:test_01";
public static String channelTopic_02="channel:test_02";
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter_01,
MessageListenerAdapter listenerAdapter_02) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//订阅两个频道
container.addMessageListener(listenerAdapter_01, new PatternTopic(channelTopic_01));
container.addMessageListener(listenerAdapter_02, new PatternTopic(channelTopic_02));
return container;
}
/**
* 消息监听器适配器,绑定消息处理器,利用反射技术调用消息处理器的业务方法
* @param receiver
* @return
*/
@Bean
MessageListenerAdapter listenerAdapter_01(RedisReceiver_01 receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
@Bean
MessageListenerAdapter listenerAdapter_02(RedisReceiver_02 receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
// @Bean
// StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
// return new StringRedisTemplate(connectionFactory);
// }
@Bean
public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<Object,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//自定义序列化方式
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//必须设置,否则无法将JSON转化为对象,会转化成Map类型
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
RedisReceiveMsg接口
RedisReceiver_01类
点击查看代码
package com.yq.demo.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yq.demo.model.User;
import org.apache.tomcat.util.json.JSONParser;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.stereotype.Component;
/**
* 接收订阅消息
* @author:yuqiang
* @date:2022.2.9
* */
@Component
public class RedisReceiver_01 implements RedisReceiveMsg{
@Override
public void receiveMessage(String message){
//如果发送的是对象,此处返回的是json格式的字符串
//通过序列号获取对象
Jackson2JsonRedisSerializer seria = new Jackson2JsonRedisSerializer(User.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
seria.setObjectMapper(objectMapper);
User user = (User)seria.deserialize(message.getBytes());
System.out.println("01 - "+message);
}
}
RedisReceiver_02类
点击查看代码
package com.yq.demo.config;
import org.springframework.stereotype.Component;
@Component
public class RedisReceiver_02 implements RedisReceiveMsg {
@Override
public void receiveMessage(String message) {
System.out.println("02 - "+message);
}
}
//字符串
redisTemplate.opsForValue().set(key,value);//value可以是字符串也可以是对象
redisTemplate.opsForValue().get(key);//获取
redisTemplate.opsForValue().set(key,user,100, TimeUnit.MILLISECONDS);//增加过期时间
redisTemplate.hasKey(key);//包含key
redisTemplate.delete(key);//删除key
long l1=redisTemplate.opsForValue().increment(key);//如果value是数字,则value+1返回+1后的值
long l2=redisTemplate.opsForValue().increment(key,100);//value+100,返回+100后的值
long l3=redisTemplate.opsForValue().decrement(key);//value-1
redisTemplate.opsForValue().append(key,"bcdef");//末尾追加字符串
redisTemplate.opsForValue().get(key,1,2);//截取字符串
redisTemplate.opsForValue().set(key2,"12",1);//字符串替换,从索引1开始后面的两个字符被12替换
boolean b=redisTemplate.opsForValue().setIfAbsent(key,value);//不存在则更新并返回true,否则返回false
boolean b=redisTemplate.opsForValue().setIfPresent(key,value);//存在则更新并返回true,否则返回false
//list
ListOperations<String,String> list =redisTemplate.opsForList();
long l1=list.leftPush("list","hello");//从左侧添加元素,返回元素总数
long l2=list.rightPush("list","world");//从右侧添加元素,返回元素总数
List
List
String str=list.index("list",1);//根据下标获取元素
list.trim("list",1,3);//只保留下标1-3的元素,包含1和3
String strV=list.leftPop("list");//从左侧弹出元素,返回弹出元素的值
long l3=list.size("list");//获取总元素个数
String strV=list.leftPop("list",10,TimeUnit.SECONDS);//从左侧弹出元素,如没有元素则等待10秒有元素则弹出返回,元素超时不再等待
//set 无序集合-去重
SetOperations<String,String> set=redisTemplate.opsForSet();
long l1=set.add("userName","Jack");//添加成功返回1
long l2=set.add("userName","Jack");//重复添加失败返回0
long l3=set.add("userName","Jone");
long l4=set.add("name","Tom");
Set
String strPop=set.pop("userName");//从集合中随机获取一个元素并将其移除
set.move("userName","Jone","name");//将userName集合中的Jone移动到集合name中,userName集合会删除Jone
Set
Set
Set
boolean b=set.isMember("userName","Jack");//检查元素是否存在于集合中
long i=set.remove("userName","Jack","Jone");//从集合中删除元素,返回删除的个数
//zset 有序集合-去重
ZSetOperations<String,String> zset=redisTemplate.opsForZSet();
//三个参数分别是key,value,score,默认按照score增序排序
//key,value相同返回false,否则返回true
boolean b=zset.add(key,"hello",1);
b=zset.add(key,"at",2);
Double d=zset.incrementScore(key,"s1",2);//与add相同分值排在2之后递增排序,返回分值
Double d=zset.incrementScore(key,"s2",2);//分值与上面的相同会排在s1后面
b=zset.add(key,"at2",2);//以上增序顺序的值为: hello,at,s1,s2,at2
long size=zset.size(key);//获取集合内元素总数
Set
Double score=zset.score(key,val);//根据key和value获取分值
Set
Set
zset.count(key,2,4);//指定分值范围内集合内元素的数量
long index=zset.rank(key,"at2");//返回成员在集合中的排序,从1开始计数
//intersectAndStore取集合1和集合2的交接赋值到集合3中,如集合3元原有元素会被清除,返回交集元素个数
Long l1 = redisTemplate.opsForZSet().intersectAndStore(key, key+"1",key+"2");//默认分值取两个集合中分值的和
Long l2=zset.intersectAndStore(key,keys,key+"3", RedisZSetCommands.Aggregate.MIN);//指定分值计算方式-交集分值取交集中较小的
//hash
HashOperations<String,Object,Object> hash=redisTemplate.opsForHash();
hash.put("user","id","1");
hash.put("user","userName","Jack");//
List
Map<String, String> map=hash.entries("user");//返回key,value
Set
hash.increment("user","id",10);//value+10
hash.size("user");//集合大小
redisTemplate.persist("key");//移除键的过期时间
redisTemplate.expire("key",100,TimeUnit.SECONDS);//为键设置过期时间
redisTemplate.getExpire("key");//获取过期时间
//事务
redisOperations.watch("a1");//监听键a1
redisOperations.multi();//开启事务
...//其他操作
List
redisOperations.unwatch();//取消监听
redisOperations.discard();//放弃事务
//流水线
redisTemplate.executePipelined(new SessionCallback
@Override
public String execute(RedisOperations operations) throws DataAccessException {
ListOperations<String, String> valueOperations=operations.opsForList();
//此处可以为任何redis的操作
for(int i=0;i<20;i++){
valueOperations.leftPush(key,String.valueOf(i));
}
return null;
}
});
//序列化
@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//自定义序列化方式
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
redisTemplate.setKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端