美文网首页
springcache redis应用 json序列化

springcache redis应用 json序列化

作者: 水叶_鸽子的信 | 来源:发表于2018-02-07 14:42 被阅读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。

    相关文章

      网友评论

          本文标题:springcache redis应用 json序列化

          本文链接:https://www.haomeiwen.com/subject/nbaozxtx.html