前言
最近在开发项目,用到了redis作为缓存,来提高系统访问速度和缓解系统压力,提高用户响应和访问速度,这里遇到几个问题做一下总结和整理
快速配置
SpringBoot整合redis有专门的场景启动器整合起来还是非常方便的
1 | xml复制代码 <dependency> |
如果使用redis连接池引入
1 | xml复制代码 <!-- redis连接池 --> |
集成配置文件
1 | yml复制代码#------------------redis缓存配置------------ |
JSON序列化
由于缓存数据默认使用的是jdk自带的序列化 二进制
需要序列化的实体类继承Serializable接口。而且序列化后的内容在redis中看起来也不是很方便。
1 | java复制代码\xAC\xED\x00\x05sr\x00Lorg.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken/\xDFGc\x9D\xD0\xC9\xB7\x02\x00\x01L\x00\x0Aexpirationt\x00\x10Ljava/util/Date;xr\x00Dorg.springframework.security.oauth2.common.DefaultOAuth2RefreshTokens\xE1\x0E\x0AcT\xD4^\x02\x00\x01L\x00\x05valuet\x00\x12Ljava/lang/String;xpt\x00$805a75f7-2ee2-4a27-a598-591bfa1cf17dsr\x00\x0Ejava.util.Datehj\x81\x01KYt\x19\x03\x00\x00xpw\x08\x00\x00\x01}y\x81\xDB\x9Ax |
于是萌生了需要将数据序列化成json的想法。
jackson序列化
在使用spring-data-redis,默认情况下是使用org.springframework.data.redis.serializer.JdkSerializationRedisSerializer这个类来做序列化,Jackson redis序列化是spring中自带的.我们使用jackson方式
1 | java复制代码@Bean |
序列化后存储在redis后内容
1 | json复制代码[ |
1 | json复制代码[ |
上面的不是严格符合json格式规范,虽然比默认二进制好
注意这里序列化json代类型
"com.qhong.test.dependBean.Person"
如果没有这个反序列化会报类型转换异常错误
也就是代码中这一段必须设置,我之前就是没有设置,反序列化都是JsonObject必须自己转换类型,否则会报错
1 | java复制代码//序列化包括类型描述 否则反向序列化实体会报错,一律都为JsonObject |
Fastjson序列化
- 需要倒入Fastjson到依赖
1 | xml复制代码<!-- JSON工具 --> |
- 实现RedisSerializer接口
1 | java复制代码import com.alibaba.fastjson.JSON; |
- 配置redisTemplate
1 | java复制代码import org.springframework.boot.autoconfigure.AutoConfigureAfter; |
注意这是一种方式自己实现RedisSerializer 序列化接口
但是FastJson 1.2.36版本以后不需要自己实现RedisSerializer
为我们提供序列化支持在com.alibaba.fastjson.support.spring中 有GenericFastJsonRedisSerializer
和FastJsonRedisSerializer
两个实现类 ,
区别在于
GenericFastJsonRedisSerializer
可以自动转换对象类型,FastJsonRedisSerializer
需要自定义转换需要的类型。
通常使用 GenericFastJsonRedisSerializer 即可满足大部分场景,如果你想定义特定类型专用的 RedisTemplate 可以使用 FastJsonRedisSerializer 来代替 GenericFastJsonRedisSerializer”
FastJson github有对应问题描述lssues 我已入坑 ,刚开始一直使用FastJsonRedisSerializer****无法自动反向序列化
序列化后存储在redis后内容
1 | json复制代码{ |
1 | json复制代码[ |
正常情况是格式是正确的,但是如果你存储内容出现set或者doubble类型,会带上Set,D类型描述如下
会出现问题无法解析,但是在程序里是可以反向序列化的
分析参考对比
jdkSerializationRedisSerializer:
使用JDK提供的序列化功能。 优点是反序列化时不需要提供类型信息(class),但缺点是需要实现Serializable接口,还有序列化后的结果非常庞大,是JSON格式的5倍左右,这样就会消耗redis服务器的大量内存。Jackson2JsonRedisSerializer:
使用Jackson库将对象序列化为JSON字符串。优点是速度快,序列化后的字符串短小精悍,不需要实现Serializable接口。但缺点也非常致命,那就是此类的构造函数中有一个类型参数,必须提供要序列化对象的类型信息(.class对象)。 通过查看源代码,发现其只在反序列化过程中用到了类型信息。FastJsonRedisSerializer
性能最优号称最快的json解析库,但是反序列化后类字段顺序和原来实体类不一致发生改变,在某些set,double字段情况下json格式不正确,但是在程序可以解析
更多问题参考
redis数据库操作
在整合了spring-boot-starter-data-redis
后会自动帮我们注入redisTemplate
对象,专门用来操作reids数据库的
在reids中如果想用文件夹方式存储key的话类似这样
我们只需要在存储使用使用::表示文件夹就可以了
1 | java复制代码redisTemplate.opsForValue().set("userLoginCache::Kenx_6003783582be4c368af14daf3495559c", "user"); |
如果需要模糊查询key话使用*
来表示 如
- 获取所有key
1 | java复制代码public static Set<String> getAllKey(String keys) { |
- 模糊批量删除
1 | java复制代码 /** |
1 | java复制代码public static void delByPrefix(String key) { |
因为使用很频繁所以我写成工具库RedisUtil
通过静态方法方式去调用就可以了
基本上包含工作中用到的所有方法, 这里附上源码
1 | java复制代码package cn.soboys.kmall.cache.utils; |
本文转载自: 掘金