43人参与 • 2026-09-07 • Redis
redistemplate.opsforvalue().set("name", "alice");
string value = redistemplate.opsforvalue().get("name");
从 java 代码层面看,这很好理解:
set("name", "alice"):把 alice 存到 key 为 name 的位置get("name"):根据 key name 把值取出来对应到 redis 命令层面,可以理解为:
set name alice get name
因为这里的 key 和 value 都是字符串,所以这个过程非常直观。
也正因为如此,<string, string> 是理解 redistemplate 数据转换的最好起点。
如果现在 value 不再是字符串,而是一个对象,例如:
user user = new user(1l, "alice", 18);
redistemplate.opsforvalue().set("user:1", user);
这时候就不能再简单理解成:
set user:1 user对象
因为 redis 命令层面并不认识 java 的 user 对象。
也就是说,对象不能直接原样放进 redis,必须先转换成 redis 能接受的形式。
最容易想到的一种方式,就是先把对象转成字符串,例如 json 字符串:
string userstring = jsonobject.tojsonstring(user);
redistemplate.opsforvalue().set("user:1", userstring);
这样到了 redis 命令层面,就更容易理解成:
set user:1 {"id":1,"name":"alice","age":18}
所以,这一步的核心认识是:
当我们从 **<string, string>** 进入 **<string, object>** 后,就会自然遇到这个问题:
这时候就需要一个“转换过程”,这个过程本质上就是序列化,你可以直接这样理解:
反过来,取值时再把它还原成 java 对象,这就是反序列化。
最原始、最容易理解的做法,就是自己手动转:
string userstring = jsonobject.tojsonstring(user);
redistemplate.opsforvalue().set("user:1", userstring);
取出来的时候再手动转回来:
string userstring = redistemplate.opsforvalue().get("user:1");
user user = jsonobject.parseobject(userstring, user.class);
这种做法的优点是:
但问题也很明显:
tojsonstringparseobject为了避免每次都手动写转换代码,就会想到封装工具类,例如:
public void set(string key, object obj) {
string str = jsonobject.tojsonstring(obj);
redistemplate.opsforvalue().set(key, str);
}
这样做的意义是:把“对象转字符串”的重复逻辑,从业务代码中抽离出去。
业务层以后就不用反复写:
jsonobject.tojsonstring(obj)
而是直接调用工具方法。
不过这里要注意一点:这仍然是你自己在 java 代码里手动做转换,只不过把它封装起来了。
现在抛弃封装 redisutils 方式,直接在 redistemplate 的配置类里,给 key 和 value 设置序列化方式。
这样之后,代码就可以直接写成:
redistemplate.opsforvalue().set("user:1", user);
这时候并不是 redis 直接认识了 user 对象,而是:
userredistemplate 会按照你配置好的序列化器,先把它转换成指定格式所以更准确的理解应该是:不是 redis 能直接存 java 对象了,而是 redistemplate 先帮我们把对象转换好了。
这就是为什么后面我们可以直接写:
redistemplate.opsforvalue().set("user:1", user);
而不用每次都手动写 jsonobject.tojsonstring(user)。
:::color3
jdk 序列化通常是 spring 体系里常见的默认方案之一。
它的特点是可以直接处理 java 对象,但在 redis 中存出来的结果通常不可读,看起来像乱码。
更准确地说,不是它“出了乱码”,而是:jdk 序列化后的内容本来就不是给人直接阅读的文本。
所以你在 redis 可视化工具里看时,会觉得它不可读。
:::color3
json 序列化会把对象转成 json 文本再存入 redis。
它的好处是:
所以很多项目里,key 用字符串序列化,value 用 json 序列化,是很常见的搭配。
:::color3
如果现成方案不能满足需求,也可以自己定义序列化规则。
也就是说,你自己决定:
这种方式灵活,但实现和维护成本更高。
package com.example.demo.config;
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.serializer.jdkserializationredisserializer;
import org.springframework.data.redis.serializer.stringredisserializer;
@configuration
public class redisjdkconfig {
@bean
public redistemplate<string, object> jdkredistemplate(redisconnectionfactory connectionfactory) {
redistemplate<string, object> redistemplate = new redistemplate<>();
redistemplate.setconnectionfactory(connectionfactory);
stringredisserializer keyserializer = new stringredisserializer();
jdkserializationredisserializer valueserializer = new jdkserializationredisserializer();
redistemplate.setkeyserializer(keyserializer);
redistemplate.sethashkeyserializer(keyserializer);
redistemplate.setvalueserializer(valueserializer);
redistemplate.sethashvalueserializer(valueserializer);
redistemplate.afterpropertiesset();
return redistemplate;
}
}
package com.example.demo.config;
import com.fasterxml.jackson.annotation.jsontypeinfo;
import com.fasterxml.jackson.databind.objectmapper;
import com.fasterxml.jackson.databind.jsontype.basicpolymorphictypevalidator;
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.serializer.genericjackson2jsonredisserializer;
import org.springframework.data.redis.serializer.stringredisserializer;
@configuration
public class redisjsonconfig {
@bean
public redistemplate<string, object> jsonredistemplate(redisconnectionfactory connectionfactory) {
redistemplate<string, object> redistemplate = new redistemplate<>();
redistemplate.setconnectionfactory(connectionfactory);
stringredisserializer keyserializer = new stringredisserializer();
objectmapper objectmapper = new objectmapper();
objectmapper.activatedefaulttyping(
basicpolymorphictypevalidator.builder()
.allowifsubtype(object.class)
.build(),
objectmapper.defaulttyping.non_final,
jsontypeinfo.as.property
);
genericjackson2jsonredisserializer valueserializer =
new genericjackson2jsonredisserializer(objectmapper);
redistemplate.setkeyserializer(keyserializer);
redistemplate.sethashkeyserializer(keyserializer);
redistemplate.setvalueserializer(valueserializer);
redistemplate.sethashvalueserializer(valueserializer);
redistemplate.afterpropertiesset();
return redistemplate;
}
}
package com.example.demo.model;
import java.io.serializable;
@data
@noargsconstructor
@allargsconstructor
public class user implements serializable {
private long id;
private string name;
private integer age;
}
package com.example.demo.serializer;
import com.example.demo.model.user;
import org.springframework.data.redis.serializer.redisserializer;
import org.springframework.data.redis.serializer.serializationexception;
import java.nio.charset.standardcharsets;
public class userredisserializer implements redisserializer<user> {
@override
public byte[] serialize(user user) throws serializationexception {
if (user == null) {
return new byte[0];
}
string value = user.getid() + "," + user.getname() + "," + user.getage();
return value.getbytes(standardcharsets.utf_8);
}
@override
public user deserialize(byte[] bytes) throws serializationexception {
if (bytes == null || bytes.length == 0) {
return null;
}
string value = new string(bytes, standardcharsets.utf_8);
string[] arr = value.split(",");
if (arr.length != 3) {
throw new serializationexception("user 反序列化失败,数据格式不正确: " + value);
}
user user = new user();
user.setid(long.parselong(arr[0]));
user.setname(arr[1]);
user.setage(integer.parseint(arr[2]));
return user;
}
}
package com.example.demo.config;
import com.example.demo.model.user;
import com.example.demo.serializer.userredisserializer;
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.serializer.stringredisserializer;
@configuration
public class rediscustomconfig {
@bean
public redistemplate<string, user> customredistemplate(redisconnectionfactory connectionfactory) {
redistemplate<string, user> redistemplate = new redistemplate<>();
redistemplate.setconnectionfactory(connectionfactory);
stringredisserializer keyserializer = new stringredisserializer();
userredisserializer valueserializer = new userredisserializer();
redistemplate.setkeyserializer(keyserializer);
redistemplate.sethashkeyserializer(keyserializer);
redistemplate.setvalueserializer(valueserializer);
redistemplate.sethashvalueserializer(valueserializer);
redistemplate.afterpropertiesset();
return redistemplate;
}
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论