redis序列化存储及日期格式
在模块开发中,使用redis做缓存是非常常见的技术,当我们注入redistempate模板时
1
|
redistemplate.opsforvalue().set( "item_" +id,itemmodel, 10 , timeunit.minutes);
|
key我们可以用固定开头和商品id进行拼接,当然正常的项目开发中最好使用多级目录进行分类,这里只做演示使用
可视化界面看到保存的数据是这样的
这样的数据是很不容易阅读的,原因是redis默认使用的是java序列化方式,在序列化时使用了redis协议中的编码。
不过在这种痛苦的数据面前做调试等工作无疑是非常不舒服的
这时候就需要我们自定义序列化方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
@configuration
public class redisconfig {
/**
* 修改redis默认的序列化方式,默认文件在redisautoconfiguration
* @param redisconnectionfactory
* @return
*/
@bean
public redistemplate redistemplate(redisconnectionfactory redisconnectionfactory){
redistemplate redistemplate = new redistemplate();
redistemplate.setconnectionfactory(redisconnectionfactory);
//设置key的序列化方式为string
stringredisserializer stringredisserializer = new stringredisserializer();
redistemplate.setkeyserializer(stringredisserializer);
//设置value的序列化方式为json
jackson2jsonredisserializer jackson2jsonredisserializer = new jackson2jsonredisserializer(object. class );
//定制化关于时间格式序列化问题
objectmapper objectmapper = new objectmapper();
simplemodule simplemodule = new simplemodule();
simplemodule.addserializer(datetime. class , new jodadatetimejsonserializer());
simplemodule.adddeserializer(datetime. class , new jodadatetimejsondeserializer());
objectmapper.registermodule(simplemodule);
//在保存结果中加入类信息,方便解析数据
objectmapper.enabledefaulttyping(objectmapper.defaulttyping.non_final);
jackson2jsonredisserializer.setobjectmapper(objectmapper);
redistemplate.setvalueserializer(jackson2jsonredisserializer);
return redistemplate;
}
}
|
1
2
3
4
5
6
|
public class jodadatetimejsonserializer extends jsonserializer<datetime> {
@override
public void serialize(datetime value, jsongenerator gen, serializerprovider serializers) throws ioexception {
gen.writestring(value.tostring( "yyyy-mm-dd hh:mm:ss" ));
}
}
|
1
2
3
4
5
6
7
8
|
public class jodadatetimejsondeserializer extends jsondeserializer<datetime> {
@override
public datetime deserialize(jsonparser p, deserializationcontext ctxt) throws ioexception, jsonprocessingexception {
string s = p.readvalueas(string. class );
datetimeformatter datetimeformatter = datetimeformat.forpattern( "yyyy-mm-dd hh:mm:ss" );
return datetime.parse(s,datetimeformatter);
}
}
|
redis序列化localdatetime报错
实体类日期字段使用localdatetime,在redis序列化时报错,会往redis中写入如下数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
"createtime" : {
"date" : {
"year" : 2019,
"month" : "may" ,
"day" : 15,
"prolepticmonth" : 24232,
"era" : [
"java.time.chrono.isoera" ,
"ce"
],
"dayofyear" : 135,
"dayofweek" : "wednesday" ,
"leapyear" : false ,
"dayofmonth" : 15,
"monthvalue" : 5,
"chronology" : {
"id" : "iso" ,
"calendartype" : "iso8601"
}
},
"time" : {
"hour" : 11,
"minute" : 3,
"second" : 43,
"nano" : 758000000
},
"dayofyear" : 135,
"dayofweek" : "wednesday" ,
"month" : "may" ,
"dayofmonth" : 15,
"year" : 2019,
"monthvalue" : 5,
"hour" : 11,
"minute" : 3,
"second" : 43,
"nano" : 758000000,
"chronology" : [
"java.time.chrono.isochronology" ,
{
"id" : "iso" ,
"calendartype" : "iso8601"
}
]
}
|
方案一:实体类日期字段添加注解
每个localdatetime类型字段都需要添加,不建议使用
1
2
3
|
@jsondeserialize (using = localdatetimedeserializer. class )
@jsonserialize (using = localdatetimeserializer. class )
private localdatetime birthday;
|
方案二:设置redis对日期序列化处理
添加配置:
1
2
3
4
5
|
// 日期序列化处理
om.disable(serializationfeature.write_dates_as_timestamps);
om.registermodule( new jdk8module())
.registermodule( new javatimemodule())
.registermodule( new parameternamesmodule());
|
完整配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
@configuration
public class redisconfig {
@bean
public redistemplate<string, object> redistemplate(redisconnectionfactory factory) {
redistemplate<string, object> template = new redistemplate<>();
// 配置连接工厂
template.setconnectionfactory(factory);
//使用jackson2jsonredisserializer来序列化和反序列化redis的value值(默认使用jdk的序列化方式)
jackson2jsonredisserializer jacksonseial = new jackson2jsonredisserializer(object. class );
objectmapper om = new objectmapper();
// 指定要序列化的域,field,get和set,以及修饰符范围,any是都有包括private和public
om.setvisibility(propertyaccessor.all, jsonautodetect.visibility.any);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如string,integer等会跑出异常
om.enabledefaulttyping(objectmapper.defaulttyping.non_final);
jacksonseial.setobjectmapper(om);
// 值采用json序列化
template.setvalueserializer(jacksonseial);
//使用stringredisserializer来序列化和反序列化redis的key值
template.setkeyserializer( new stringredisserializer());
// 设置hash key 和value序列化模式
template.sethashkeyserializer( new stringredisserializer());
template.sethashvalueserializer(jacksonseial);
template.afterpropertiesset();
// 日期序列化处理
om.disable(serializationfeature.write_dates_as_timestamps);
om.registermodule( new jdk8module())
.registermodule( new javatimemodule())
.registermodule( new parameternamesmodule());
return template;
}
}
|
以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/qq_15038565/article/details/108418122