• Spring整合Redis(spring-data-redis)


    历经几天看了大量的博客资料,差不多算是搞定了,目前只是针对单个数据源,集群暂时没研究

    maven依赖

    <properties>
        <!-- redis 版本 -->
        <redis.version>2.9.0</redis.version>
        <spring.redis.version>1.8.4.RELEASE</spring.redis.version>
    </properties>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>${redis.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>${spring.redis.version}</version>
    </dependency>

    redis.properties

    redis.host=127.0.0.1
    redis.port=6379
    redis.password=""
    redis.maxIdle=400
    redis.maxTotal=6000
    redis.maxWaitMillis=1000
    redis.blockWhenExhausted=true
    redis.testOnBorrow=true
    redis.timeout=100000
    defaultCacheExpireTime=60

    spring-redis.xml

    <?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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd   
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context-4.3.xsd"
        default-lazy-init="false">
        
        <!-- 加载配置文件 -->  
        <context:property-placeholder location="classpath:redis.properties" />  
        <!-- redis数据源 -->
        <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <!-- 最大空闲数 -->
            <property name="maxIdle" value="${redis.maxIdle}" />
            <!-- 最大空连接数 -->
            <property name="maxTotal" value="${redis.maxTotal}" />
            <!-- 最大等待时间 -->
            <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
            <!-- 连接超时时是否阻塞,false时报异常,ture阻塞直到超时, 默认true -->
             <property name="blockWhenExhausted" value="${redis.blockWhenExhausted}" /> 
            <!-- 返回连接时,检测连接是否成功 -->
            <property name="testOnBorrow" value="${redis.testOnBorrow}" />
        </bean>
    
        <!-- Spring-redis连接池管理工厂 -->
        <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
            <!-- IP地址 -->
            <property name="hostName" value="${redis.host}" />
            <!-- 端口号 -->
            <property name="port" value="${redis.port}" />
            <!-- 超时时间 默认2000-->
            <property name="timeout" value="${redis.timeout}" />
            <!-- 连接池配置引用 -->
            <property name="poolConfig" ref="poolConfig" />
            <!-- usePool:是否使用连接池 -->
            <property name="usePool" value="true"/>
        </bean>
    
        <!-- redis template definition -->
        <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
            <property name="connectionFactory" ref="jedisConnectionFactory" />
            <property name="keySerializer">
                <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
            </property>
            <property name="valueSerializer">
                <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
            </property>
            <property name="hashKeySerializer">
                <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
            </property>
            <property name="hashValueSerializer">
                <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
            </property>
             <!--开启事务  -->  
            <property name="enableTransactionSupport" value="true"></property>  
        </bean>
        
        <!--自定义redis工具类,在需要缓存的地方注入此类  -->  
        <bean id="redisrCacheManager" class="com.phil.common.redis.RedisCacheManager">  
            <property name="redisTemplate" ref="redisTemplate" />  
        </bean>
    </beans>

    RedisCacheManager.java

    package com.phil.common.redis;
    
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.util.CollectionUtils;
    
    /**
     * Redis Util
     * @author phil
     * @date 2017年8月14日
     *
     */
    public class RedisCacheManager {
        
        private RedisTemplate<String, Object> redisTemplate;
    
        public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
            this.redisTemplate = redisTemplate;
        }
    
        
        /**
         * 指定缓存失效时间
         * 
         * @param key
         *            键
         * @param time
         *            时间(秒)
         * @return
         */
        public boolean expire(String key, long time) {
            try {
                if (time > 0) {
                    redisTemplate.expire(key, time, TimeUnit.SECONDS);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 根据key 获取过期时间
         * 
         * @param key
         *            键 不能为null
         * @return 时间(秒) 返回0代表为永久有效
         */
        public long getExpire(String key) {
            return redisTemplate.getExpire(key, TimeUnit.SECONDS);
        }
    
        /**
         * 判断key是否存在
         * 
         * @param key
         *            键
         * @return true 存在 false不存在
         */
        public boolean hasKey(String key) {
            try {
                return redisTemplate.hasKey(key);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 删除缓存
         * 
         * @param key
         *            可以传一个值 或多个
         */
        @SuppressWarnings("unchecked")
        public void del(String... key) {
            if (key != null && key.length > 0) {
                if (key.length == 1) {
                    redisTemplate.delete(key[0]);
                } else {
                    redisTemplate.delete(CollectionUtils.arrayToList(key));
                }
            }
        }
    
        // ============================String=============================
        /**
         * 普通缓存获取
         * 
         * @param key
         *            键
         * @return*/
        public Object get(String key) {
            return key == null ? null : redisTemplate.opsForValue().get(key);
        }
    
        /**
         * 普通缓存放入
         * 
         * @param key
         *            键
         * @param value
         *            值
         * @return true成功 false失败
         */
        public boolean set(String key, Object value) {
            try {
                redisTemplate.opsForValue().set(key, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
    
        }
    
        /**
         * 普通缓存放入并设置时间
         * 
         * @param key
         *            键
         * @param value
         *            值
         * @param time
         *            时间(秒) time要大于0 如果time小于等于0 将设置无限期
         * @return true成功 false 失败
         */
        public boolean set(String key, Object value, long time) {
            try {
                if (time > 0) {
                    redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
                } else {
                    set(key, value);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 递增
         * 
         * @param key
         *            键
         * @param by
         *            要增加几(大于0)
         * @return
         */
        public long incr(String key, long delta) {
            if (delta < 0) {
                throw new RuntimeException("递增因子必须大于0");
            }
            return redisTemplate.opsForValue().increment(key, delta);
        }
    
        /**
         * 递减
         * 
         * @param key
         *            键
         * @param by
         *            要减少几(小于0)
         * @return
         */
        public long decr(String key, long delta) {
            if (delta < 0) {
                throw new RuntimeException("递减因子必须大于0");
            }
            return redisTemplate.opsForValue().increment(key, -delta);
        }
    
        // ================================Map=================================
        /**
         * HashGet
         * 
         * @param key
         *            键 不能为null
         * @param item
         *            项 不能为null
         * @return*/
        public Object hget(String key, String item) {
            return redisTemplate.opsForHash().get(key, item);
        }
    
        /**
         * 获取hashKey对应的所有键值
         * 
         * @param key
         *            键
         * @return 对应的多个键值
         */
        public Map<Object, Object> hmget(String key) {
            return redisTemplate.opsForHash().entries(key);
        }
    
        /**
         * HashSet
         * 
         * @param key
         *            键
         * @param map
         *            对应多个键值
         * @return true 成功 false 失败
         */
        public boolean hmset(String key, Map<String, Object> map) {
            try {
                redisTemplate.opsForHash().putAll(key, map);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * HashSet 并设置时间
         * 
         * @param key
         *            键
         * @param map
         *            对应多个键值
         * @param time
         *            时间(秒)
         * @return true成功 false失败
         */
        public boolean hmset(String key, Map<String, Object> map, long time) {
            try {
                redisTemplate.opsForHash().putAll(key, map);
                if (time > 0) {
                    expire(key, time);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 向一张hash表中放入数据,如果不存在将创建
         * 
         * @param key
         *            键
         * @param item
         *            项
         * @param value
         *            值
         * @return true 成功 false失败
         */
        public boolean hset(String key, String item, Object value) {
            try {
                redisTemplate.opsForHash().put(key, item, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 向一张hash表中放入数据,如果不存在将创建
         * 
         * @param key
         *            键
         * @param item
         *            项
         * @param value
         *            值
         * @param time
         *            时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
         * @return true 成功 false失败
         */
        public boolean hset(String key, String item, Object value, long time) {
            try {
                redisTemplate.opsForHash().put(key, item, value);
                if (time > 0) {
                    expire(key, time);
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 删除hash表中的值
         * 
         * @param key
         *            键 不能为null
         * @param item
         *            项 可以使多个 不能为null
         */
        public void hdel(String key, Object... item) {
            redisTemplate.opsForHash().delete(key, item);
        }
    
        /**
         * 判断hash表中是否有该项的值
         * 
         * @param key
         *            键 不能为null
         * @param item
         *            项 不能为null
         * @return true 存在 false不存在
         */
        public boolean hHasKey(String key, String item) {
            return redisTemplate.opsForHash().hasKey(key, item);
        }
    
        /**
         * hash递增 如果不存在,就会创建一个 并把新增后的值返回
         * 
         * @param key
         *            键
         * @param item
         *            项
         * @param by
         *            要增加几(大于0)
         * @return
         */
        public double hincr(String key, String item, double by) {
            return redisTemplate.opsForHash().increment(key, item, by);
        }
    
        /**
         * hash递减
         * 
         * @param key
         *            键
         * @param item
         *            项
         * @param by
         *            要减少记(小于0)
         * @return
         */
        public double hdecr(String key, String item, double by) {
            return redisTemplate.opsForHash().increment(key, item, -by);
        }
    
        // ============================set=============================
        /**
         * 根据key获取Set中的所有值
         * 
         * @param key
         *            键
         * @return
         */
        public Set<Object> sGet(String key) {
            try {
                return redisTemplate.opsForSet().members(key);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * 根据value从一个set中查询,是否存在
         * 
         * @param key
         *            键
         * @param value
         *            值
         * @return true 存在 false不存在
         */
        public boolean sHasKey(String key, Object value) {
            try {
                return redisTemplate.opsForSet().isMember(key, value);
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 将数据放入set缓存
         * 
         * @param key
         *            键
         * @param values
         *            值 可以是多个
         * @return 成功个数
         */
        public long sSet(String key, Object... values) {
            try {
                return redisTemplate.opsForSet().add(key, values);
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    
        /**
         * 将set数据放入缓存
         * 
         * @param key
         *            键
         * @param time
         *            时间(秒)
         * @param values
         *            值 可以是多个
         * @return 成功个数
         */
        public long sSetAndTime(String key, long time, Object... values) {
            try {
                Long count = redisTemplate.opsForSet().add(key, values);
                if (time > 0)
                    expire(key, time);
                return count;
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    
        /**
         * 获取set缓存的长度
         * 
         * @param key
         *            键
         * @return
         */
        public long sGetSetSize(String key) {
            try {
                return redisTemplate.opsForSet().size(key);
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    
        /**
         * 移除值为value的
         * 
         * @param key
         *            键
         * @param values
         *            值 可以是多个
         * @return 移除的个数
         */
        public long setRemove(String key, Object... values) {
            try {
                Long count = redisTemplate.opsForSet().remove(key, values);
                return count;
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
        // ===============================list=================================
    
        /**
         * 获取list缓存的内容
         * 
         * @param key
         *            键
         * @param start
         *            开始
         * @param end
         *            结束 0 到 -1代表所有值
         * @return
         */
        public List<Object> lGet(String key, long start, long end) {
            try {
                return redisTemplate.opsForList().range(key, start, end);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * 获取list缓存的长度
         * 
         * @param key
         *            键
         * @return
         */
        public long lGetListSize(String key) {
            try {
                return redisTemplate.opsForList().size(key);
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    
        /**
         * 通过索引 获取list中的值
         * 
         * @param key
         *            键
         * @param index
         *            索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
         * @return
         */
        public Object lGetIndex(String key, long index) {
            try {
                return redisTemplate.opsForList().index(key, index);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * 将list放入缓存
         * 
         * @param key
         *            键
         * @param value
         *            值
         * @param time
         *            时间(秒)
         * @return
         */
        public boolean lSet(String key, Object value) {
            try {
                redisTemplate.opsForList().rightPush(key, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 将list放入缓存
         * 
         * @param key
         *            键
         * @param value
         *            值
         * @param time
         *            时间(秒)
         * @return
         */
        public boolean lSet(String key, Object value, long time) {
            try {
                redisTemplate.opsForList().rightPush(key, value);
                if (time > 0)
                    expire(key, time);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 将list放入缓存
         * 
         * @param key
         *            键
         * @param value
         *            值
         * @param time
         *            时间(秒)
         * @return
         */
        public boolean lSet(String key, List<Object> value) {
            try {
                redisTemplate.opsForList().rightPushAll(key, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 将list放入缓存
         * 
         * @param key
         *            键
         * @param value
         *            值
         * @param time
         *            时间(秒)
         * @return
         */
        public boolean lSet(String key, List<Object> value, long time) {
            try {
                redisTemplate.opsForList().rightPushAll(key, value);
                if (time > 0)
                    expire(key, time);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 根据索引修改list中的某条数据
         * 
         * @param key
         *            键
         * @param index
         *            索引
         * @param value
         *            值
         * @return
         */
        public boolean lUpdateIndex(String key, long index, Object value) {
            try {
                redisTemplate.opsForList().set(key, index, value);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
    
        /**
         * 移除N个值为value
         * 
         * @param key
         *            键
         * @param count
         *            移除多少个
         * @param value
         *            值
         * @return 移除的个数
         */
        public long lRemove(String key, long count, Object value) {
            try {
                Long remove = redisTemplate.opsForList().remove(key, count, value);
                return remove;
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
    }

    实际使用

    比如微信的access_token有效期只有2小时,不可能即用即获取

    package com.phil.common.listener;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.event.ContextRefreshedEvent;
    import org.springframework.stereotype.Component;
    
    import com.phil.common.config.WechatConfig;
    import com.phil.common.redis.RedisCacheManager;
    import com.phil.common.util.HttpReqUtil;
    
    /**
     * 初始化生成微信token
     * @author phil
     * @date 2017年7月9日
     *
     */
    @Component
    public class InitWechatAuthListener implements ApplicationListener<ContextRefreshedEvent> {
    
        //private static final Logger logger = Logger.getLogger(InitWechatAuthListener.class);
        
        @Autowired
        private RedisCacheManager redisCacheManager;
    
        private static boolean isStart = false; // 防止二次调用
    
        @Override
        public void onApplicationEvent(ContextRefreshedEvent event) {
            if (!isStart) {
                isStart = true;
                String token = HttpReqUtil.getAccessToken(WechatConfig.APP_ID,WechatConfig.APP_SECRET);
                redisCacheManager.set("phil_token", token, 3600); //1小时
            }
        }
    }
    /**
     * 
     */
    package com.phil.wechatqrcode.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    import com.phil.common.config.WechatConfig;
    import com.phil.common.redis.RedisCacheManager;
    import com.phil.common.util.HttpReqUtil;
    import com.phil.wechatqrcode.service.WechatQRCodeService;
    
    /**
     * 微信带参二维码
     * @author phil
     * @date  2017年7月24日
     *
     */
    public class WechatQRCodeController {
        
        @Autowired
        private WechatQRCodeService wechatQRCodeService;
        
        @Autowired
        private RedisCacheManager redisCacheManager;
        
        public String test() {
            Object object = redisCacheManager.get("phil_token");
            if(object ==null){
                redisCacheManager.set("phil_token", HttpReqUtil.getAccessToken(WechatConfig.APP_ID, WechatConfig.APP_SECRET), 3600);
                object = redisCacheManager.get("phil_token");
            }
            wechatQRCodeService.createForeverStrTicket(object.toString(), "123");
            return null;
        }
    }

    以上只是个示例,自己视情况改写和重新封装

  • 相关阅读:
    Alpha冲刺(1/4)
    团队项目用户验收评审
    beta冲刺 第四天
    beta冲刺 第三天
    Beta冲刺 第二天
    Beta冲刺 第一天
    实验十一 团队作业7---团队项目设计完善&编码测试
    Alpha冲刺四
    Alpha冲刺
    《Miracle_House》团队项目系统设计改进
  • 原文地址:https://www.cnblogs.com/phil_jing/p/7468586.html
Copyright © 2020-2023  润新知