springcache redis应用 json序列化

2018-02-07  本文已影响0人  水叶_鸽子的信

事在人为,是一种积极的人生态度;随遇而安,是一种乐观的处世妙方;顺其自然,是一种豁达的生存之道;水到渠成,是一种高超的入世智慧。 不保留的,才叫青春;不解释的,才叫从容;不放手的,才叫真爱;不完美的,才叫人生。 对世界好奇,对事业尊重,对生命敬畏,对家人负责。心态平和,坚持幽默,做个好人! --排骨营养汤

1. 配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/cache 
        http://www.springframework.org/schema/cache/spring-cache-4.3.xsd">
    
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="${redis.pool.maxTotal}" />
        <property name="maxIdle" value="${redis.pool.maxIdle}" />
        <property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" />
        <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
    </bean>
        
    <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
        <property name="hostName" value="${redis.ip}" />
        <property name="password" value="${redis.password}" />
        <property name="port" value="${redis.port}" />
        <property name="poolConfig" ref="jedisPoolConfig" />
        <property name="timeout" value="${redis.timeout}" />
    </bean>
    <!-- JSON序列化,空间占用小,无需指明但对象类型 -->
    <bean id="genericJackson2JsonRedisSerializer" class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
    
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="keySerializer" ref="genericJackson2JsonRedisSerializer">
            <!-- <bean  class="org.springframework.data.redis.serializer.StringRedisSerializer" /> -->
        </property>
        <property name="hashKeySerializer" ref="genericJackson2JsonRedisSerializer">
            <!-- <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> -->
        </property>
        <property name="valueSerializer" ref="genericJackson2JsonRedisSerializer">
            <!-- <bean class="org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer" /> -->
        </property>
        <property name="hashValueSerializer" ref="genericJackson2JsonRedisSerializer">
            <!-- <bean class="org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer" /> -->
        </property>
        <property name="connectionFactory" ref="jedisConnectionFactory" />
    </bean>
    
     <!-- spring自己的缓存管理器,这里定义了缓存位置名称 ,即注解中的value -->    
     <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">    
         <property name="caches">    
            <set>      
                <!-- 编码1 -->
                <bean class="RedisCache">    
                     <property name="redisTemplate" ref="redisTemplate" />    
                     <property name="name" value="code1"/>
                     <property name="timeout" value="${redis.timeout}"/>    
                </bean>
                <!-- 编码2 -->
                <bean class="RedisCache">    
                     <property name="redisTemplate" ref="redisTemplate" />    
                     <property name="name" value="code2"/>    
                     <property name="timeout" value="${redis.timeout}"/>
                </bean>
           
         </property>
             
     </bean>    
</beans>

以上配置文件实现了

  1. json格式的序列化
  2. code1和code2两个key值的管理
  3. redis的基本配置

2. 管理类

/**
* @author 
* @version 创建时间:2017年12月12日 下午2:13:10
* 
*/
import java.util.concurrent.Callable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;

public class RedisCache implements Cache {

    private RedisTemplate<String, Object> redisTemplate;
    private String name;

    @Autowired
    private JedisDao jedisDao;

    private long timeout;

    @Autowired
    private GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer;

    public RedisTemplate<String, Object> getRedisTemplate() {
        return redisTemplate;
    }

    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return this.name;
    }

    public long getTimeout() {
        return timeout;
    }

    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }

    @Override
    public Object getNativeCache() {
        return this.redisTemplate;
    }

    @Override
    public ValueWrapper get(Object key) {
        final String keyf = key.toString();
        Object object = null;
        object = redisTemplate.execute(new RedisCallback<Object>() {
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                // byte[] key = keyf.getBytes();
                byte[] value = connection.hGet(name.getBytes(), keyf.getBytes());
                if (value == null) {
                    return null;
                }
                return toObject(value);
            }
        });
        return (object != null ? new SimpleValueWrapper(object) : null);
    }

    @Override
    public void put(Object key, Object value) {
        final String keyf = key.toString();
        final Object valuef = value;
        redisTemplate.execute(new RedisCallback<Long>() {
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                connection.hSet(name.getBytes(), keyf.getBytes(), toByteArray(valuef));
                if (timeout > 0) {
                    connection.expire(name.getBytes(), timeout);
                }
                return 1L;
            }
        });
    }

    private byte[] toByteArray(Object obj) {
        return genericJackson2JsonRedisSerializer.serialize(obj);
    }

    private Object toObject(byte[] bytes) {
        return genericJackson2JsonRedisSerializer.deserialize(bytes);
    }

    @Override
    public void evict(Object key) {
        final String keyf = key.toString();
        redisTemplate.execute(new RedisCallback<Long>() {
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.del(keyf.getBytes());
            }
        });
    }

    @Override
    public void clear() {
        redisTemplate.execute(new RedisCallback<String>() {
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                connection.del(name.getBytes());
                return "ok";
            }
        });
    }

    @Override
    public <T> T get(Object key, Class<T> type) {
        return null;
    }

    @Override
    public ValueWrapper putIfAbsent(Object key, Object value) {
        return null;
    }

    @Override
    public <T> T get(Object key, Callable<T> valueLoader) {
        return null;
    }

}

3.使用

1.code1缓存管理

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Service;

public class Code1{

 
    @CacheEvict(value = "code1", allEntries = true)
    public boolean saveOrUpdate() {
        return true;
    }

    
    @Cacheable(value = "code1", key = "'queryById_' + #id")
    public List<Long> queryById(String id) {
        return ...;
    }

    
    @Cacheable(value = "code1", key = "'queryByName_' + #name")
    public List<Long> queryByName(String name) {
        return ...;
    }
}
1.该类实现了对code1为code值的HashMap的管理
2.在redis中结果应该是
code1--->queryById_1-->List<Long>
                 queryById_2-->List<Long>
                              ....
                 queryById_n-->List<Long>
                               ...
                 queryByName_name1-->List<Long>
                 queryByName_name2-->List<Long>
                               ...
                 queryByName_name3-->List<Long>

当调用saveOrUpdate方法时,会触发RedisCache 中的evict,这样就会清空掉以code1为key值的所有redis缓存的数据。
当触发queryById()时,会先触发RedisCache 中的get方法,如果查询到了数据则直接返回,不再进入到queryById()方法里,如果未查询到结果则会把查询出来的数据通过调用RedisCache 中的put方法,插入到redis中,建立缓存,以待下次查询时使用。

2.code2管理

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Service;

public class Code2{

    @CacheEvict(value = "code2", allEntries = true)
    public boolean saveOrUpdate() {
        return true;
    }

    
    @Cacheable(value = "code2", key = "#root.target.getCacheMapJson(#map)")
    public List<Long> query(Map<String, Object> map) {
        return ...;
    }

    public String getCacheMapJson(Map<String, Object> map) {
        return JSON.toJSONString(map);
    }
}

code2类与code1的区别是,实现了getCacheMapJson方法,复杂的查询条件进行序列化,该方法必须为public。

上一篇下一篇

猜你喜欢

热点阅读