深入理解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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM