深入理解Spring Redis的使用 (七)、Spring Redis 使用 jackson序列化 以及 BaseDao代码
之前在介绍Spring Redis进行存储的时候,都是通过RedisTemplate中的defaultSerializer,即JdkSerializationRedisSerializer。通过Jdk的序列化比较简单,但是有时候线上调试的时候通过控制台查看,完全看不出来存储了什么东西。而且在空间占用和性能上,相比Jackson,完全没有优势。
有过两次线上出问题,定位的时候知道缓存有错,却不知道到底出在那个缓存的字段上,调试非常不方便。于是序列化统统换成了Jackson。
代码如下:

import java.lang.reflect.ParameterizedType;
import java.util.concurrent.TimeUnit; import javax.annotation.Resource; import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
/**
* key统一为String,省略.HK为hash类型的hashkey类型,HV为value类型或者hashvalue类型(这两个不可能同时存在,所以只取一个)
* @author Han
*/
public class BaseRedisDao<HK, HV> implements InitializingBean{ //实际参数的class start
private Class<HK> hkClass; private Class<HV> hvClass; private Class<HK> getHKClass(){
if (hkClass == null) {
hkClass = (Class<HK>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
return hkClass;
} private Class<HV> getHVClass(){
if (hvClass == null) {
hvClass = (Class<HV>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
}
return hvClass;
}
// end
@Autowired
private RedisTemplate<String, HV> redisTemplate; protected ValueOperations<String, HV> valueOperations;
//
protected HashOperations<String, HK, HV> hashOperations;
//
protected ListOperations<String, HV> listOperations; protected SetOperations<String, HV> setOperations;
/**
*
* @param key
* @param value
* @param expire
* @return
*/
protected void set(String key, HV value, long expire) {
valueOperations.set(key, value, expire, TimeUnit.SECONDS);
} /**
* get value
*
* @param key
* @return
*/
protected HV get(String key) {
return valueOperations.get(key);
} /**
* key delete
* @param key
*/
protected void delete(String key){
getRedisTemplate().delete(key);
} /**
* key exist
* @param key
* @return
*/
protected boolean hasKey(String key){
return getRedisTemplate().hasKey(key);
}
/**
*key expire
* @param key
* @param timeout
* @param unit
* @return
*/
protected Boolean expire(String key,long timeout,TimeUnit unit){
return getRedisTemplate().expire(key, timeout, unit);
}
/**
* redistemplate是全局唯一的,子类不要出现对redistemplate的成员变量的设置(比如keyserializer,)
* @return
*/
RedisTemplate<String, HV> getRedisTemplate() {
return redisTemplate;
}
/**
* 当需要更改serializer,可以直接通过connection.set等方法实现
* @param callback
* @return
*/
protected <T> T execute(RedisCallback<T> callback){
return redisTemplate.execute(callback);
}
/**
* 获取stringserializer
*/
protected RedisSerializer<String> getStringSerializer(){
return redisTemplate.getStringSerializer();
}
/**
* 获取JdkSerializationRedisSerializer
*/
@SuppressWarnings("unchecked")
protected <T> RedisSerializer<T> getDefaultSerializer(){
return (RedisSerializer<T>) redisTemplate.getDefaultSerializer();
}
/**
* 获取stringserializer
* @return
*/
@SuppressWarnings("unchecked")
protected RedisSerializer<String> getKeySerializer(){
return (RedisSerializer<String>) redisTemplate.getKeySerializer();
}
/**
* 获取jackson2jsonredisserializer
* @return
*/
protected RedisSerializer<HV> getValueSerializer(){
return (RedisSerializer<HV>) redisTemplate.getValueSerializer();
}
/**
* 获取jackson2jsonredisserializer
* @return
*/
@SuppressWarnings("unchecked")
protected RedisSerializer<HK> getHashKeySerializer() {
return (RedisSerializer<HK>) redisTemplate.getHashKeySerializer();
} /**
* 获取jackson2jsonredisserializer
* @return
*/
@SuppressWarnings("unchecked")
protected RedisSerializer<HV> getHashValueSerializer() {
return (RedisSerializer<HV>) redisTemplate.getHashValueSerializer();
} @Override
public void afterPropertiesSet() throws Exception {
if(getHKClass() == null || getHVClass() == null){
throw new IllegalArgumentException("获取泛型class失败");
}
//
valueOperations = redisTemplate.opsForValue();
hashOperations = redisTemplate.opsForHash();
listOperations = redisTemplate.opsForList();
setOperations = redisTemplate.opsForSet();
//
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<HV>(getHVClass()));
redisTemplate.setHashKeySerializer(new Jackson2JsonRedisSerializer<HK>(getHKClass()));
redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<HV>(getHVClass()));
}
}

对于key的序列化,直接在配置文件定义

<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" scope="prototype">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<property name="keySerializer" ref="stringKeySerializer"/>
<property name="enableTransactionSupport" value="true"/><!-- 配置true可以使用transactional控制事务,spring已经提供支持 -->
</bean>

深入理解Spring Redis的使用 (七)、Spring Redis 使用 jackson序列化 以及 BaseDao代码的更多相关文章
- Redis系列(七)Redis面试题
Redis 系列: Redis系列(一)Redis入门 Redis系列(二)Redis的8种数据类型 Redis系列(三)Redis的事务和Spring Boot整合 Redis系列(四)Redis配 ...
- redis学习(七)redis主从复制
redis主从复制 1.redis主从复制的作用 redis的定位是一个高可用的数据服务器,可是在实际生产环境下,单机的redis服务器是无法满足真正意义上的高可用性的. 第一,单机的redis服务器 ...
- Redis实战(七)Redis开发与运维
Redis用途 1.缓存 Redis提供了键值过期时间设置, 并且也提供了灵活控制最大内存和内存溢出后的淘汰策略. 可以这么说, 一个合理的缓存设计能够为一个网站的稳定保驾护航. 2.排行榜系统 Re ...
- Redis总结(七)Redis运维常用命令
redis 服务器端命令 redis 127.0.0.1:6380> time ,显示服务器时间 , 时间戳(秒), 微秒数 1) "1375270361" 2) &quo ...
- 【Redis】Redis学习(七) Redis 持久化之RDB和AOF
Redis 持久化提供了多种不同级别的持久化方式:一种是RDB,另一种是AOF. RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot). AOF ...
- Redis总结(七)Redis运维常用命令(转载)
redis 服务器端命令 redis 127.0.0.1:6380> time ,显示服务器时间 , 时间戳(秒), 微秒数 1) "1375270361" 2) &quo ...
- redis之(七)redis的集合类型的命令
[一]增加/删除元素 --->命令:SADD key member [member...] --->向集合键中添加一个,或多个元素.如果键不存在,则创建.如果元素存在,则忽略不执行.返回值 ...
- 第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第七天】(redis缓存)
https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...
- Java缓存相关memcached、redis、guava、Spring Cache的使用
随笔分类 - Java缓存相关 主要记录memcached.redis.guava.Spring Cache的使用 第十二章 redis-cluster搭建(redis-3.2.5) 摘要: redi ...
随机推荐
- loadrunner使用过程遇到的问题(一)
1.如果log日志出现乱码,如何设置?(对于乱码设置只是对单一脚本有效,并不是全部脚本有效,所以多个脚本出现乱码,需要逐个设置) loadrunner12版本设置方法,在preference里面,设置 ...
- arm寄存器
ARM 处理器拥有 37 个寄存器. 这些寄存器按部分重叠组方式加以排列. 每个处理器模式都有一个不同的寄存器组. 编组的寄存器为处理处理器异常和特权操作提供了快速的上下文切换. 提供了下列寄存器:三 ...
- auth组件
Django auth认证组件 简介 ''' Django auth认证组件提供了用户表的构建方式,认证接口,会话登录与注销接口. 中间件将会话登录用户保存到request对象中,这样不用从会话中获取 ...
- Jenkins编辑或替换All view
为什么我不能编辑“All”view? 这是因为它的类型是“All”而不是“List”,并且“All”类型是不可编辑的.你只能有一个“All”类型的view. 如果你想编辑这个View,你将不得不创建一 ...
- Linux 允许或者禁止ping
Linux默认是允许Ping响应的,系统是否允许Ping由2个因素决定的:A.内核参数,B.防火墙,需要2个因素同时允许才能允许Ping,2个因素有任意一个禁Ping就无法Ping. 具体的配置方法如 ...
- ubuntu安装时系统分区设置
1. 创建主分区:主分区,用于存放系统 20G 主分区 空间起始位置 Ext4日志文件系统 / 2. 创建swap分区:逻辑分区.大小设置为电脑内存大小,2G: 2048MB ...
- 如何在电脑上配置两个tomcat
问题 准备逐渐转向idea的怀抱了,每次部署项目时和eclipse使用的都是同一个tomcat,这是很大的隐患,并且非常的不方便,遂再配置一个tomcat 1.下载tomcat和配置系统变量 CATA ...
- margin与padding的bug
1.在页面布局时,值对于块元素来说,相邻的两个兄弟块元素间的margin-top与上一个兄弟的margin-bottom重合时, 解决办法:对其中一个块元素中设置 display:inline- ...
- LDAP & Implementation
LDAP & Implementation 一.什么是LDAP? (一)在介绍什么是LDAP之前,我们先来复习一个东西:“什么是目录服务?” 1. 目录服务是一个特殊的数据库,用来保存描述性的 ...
- Vue中scoped css和css module比较
scoped css 官方文档 scoped css可以直接在能跑起来的vue项目中使用. 使用方法: <style scoped> h1 { color: #f00; } </st ...