zoukankan      html  css  js  c++  java
  • spring3.0结合Redis在项目中的运用

    推荐一个程序员的论坛网站:http://ourcoders.com/home/

    以下内容使用到的技术有:Redis缓存、SpringMVC、Maven。项目中使用了redis缓存,目的是在业务场景中,提高SQL的查询效率,做出性能优化。先看pom.xml的配置文件中,Jedis是Redis的Java客户端,Jedis基本实现了Redis的所有功能。在使用的时候,我们创建一个Jedis对象,通过操作Jedis来操作Redis,实现我们的业务场景需求。项目中使用了Maven来托管,先看Jedis在pom文件中的配置如下:

     1         <!-- Redis -->
     2         <dependency>
     3             <groupId>redis.clients</groupId>
     4             <artifactId>jedis</artifactId>
     5             <version>2.7.0</version>
     6         </dependency>
     7 
     8         <dependency>
     9             <groupId>org.springframework.data</groupId>
    10             <artifactId>spring-data-redis</artifactId>
    11             <version>1.5.0.RELEASE</version>
    12         </dependency>
    pom.xml中redis的配置文件

    我们的pom.xml配置文件中共有两部分,上述配置会导入jedis-2.7.0.jar包和spring-data-redis.jar包。我们再看配置文件app-context-cache.xml,其中配置了ip地址,端口号,以及数据库的访问密码。这部分配置利用了maven编译时,会扫描相应的配置文件动态加载,如maven会根据:dev.properties、pre.properties、production.properties;开发、测试、生产生成相应的配置文件:详情如下:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
     4     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     5         http://www.springframework.org/schema/beans/spring-beans.xsd">
     6 
     7     <!-- redis -->
     8     <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
     9         <property name="maxTotal" value="100" />
    10         <property name="maxIdle" value="20" />
    11         <property name="timeBetweenEvictionRunsMillis" value="30000" />
    12         <property name="minEvictableIdleTimeMillis" value="30000" />
    13         <property name="testOnBorrow" value="true" />
    14     </bean>
    15     <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
    16         <property name="poolConfig" ref="jedisPoolConfig" />
    17         <property name="hostName">
    18             <value>${redis.address}</value>
    19         </property>
    20         <property name="port">
    21             <value>${redis.port}</value>
    22         </property>
    23         <property name="password">
    24             <value>${redis.password}</value>
    25         </property>
    26         <property name="timeout" value="15000"></property>
    27         <property name="usePool" value="true"></property>
    28     </bean>
    29     <bean id="jedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    30         <property name="connectionFactory" ref="jedisConnectionFactory"></property>
    31         <property name="keySerializer">
    32             <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    33         </property>
    34         <property name="valueSerializer">
    35             <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
    36         </property>
    37     </bean>
    38     
    39     <bean id="cacheService" class="xx.xx.xx.xx.CacheService" />
    40 
    41 </beans>
    app-context-cache.xml配置文件

    其中<bean id="cacheService" class="xx.xx.xx.xx.CacheService" />指定了缓存类所在的package包中。再来看具体的CacheService的使用。

      1 /**
      2  * 缓存操作
      3  */
      4 public class CacheService {
      5 
      6     protected Logger logger = LoggerFactory.getLogger(getClass());
      7 
      8     @Autowired
      9     private RedisTemplate<String, Object> redisTemplate;
     10 
     11     /*
     12      * 缓存最大过期时间-一个月
     13      */
     14     public static final int EXPIRE_TIME_MAX = 30 * 24 * 3600;
     15 
     16     /*
     17      * 缓存过期时间-半天
     18      */
     19     public static final int EXPIRE_TIME_HALFDAY = 12 * 3600;
     20 
     21     /*
     22      * 缓存过期时间-整天
     23      */
     24     public static final int EXPIRE_TIME_ONEDAY = 24 * 3600;
     25 
     26     /******************************
     27      ********* 缓存操作 ***********
     28      ******************************/
     29 
     30     /**
     31      * 设置缓存
     32      * 
     33      * @param key
     34      * @param value
     35      */
     36     public void putCache(String key, Object value) {
     37         try {
     38             redisTemplate.opsForValue().set(key, value);
     39         } catch (Exception e) {
     40             logger.error("PUT cache exception [key=" + key + ", value=" + value + "].", e);
     41         }
     42     }
     43 
     44     /**
     45      * 设置缓存,并设定缓存时长(秒)
     46      * 
     47      * @param key
     48      * @param value
     49      * @param expire
     50      */
     51     public void putCache(String key, Object value, int expire) {
     52         try {
     53 
     54             redisTemplate.opsForValue().set(key, value, expire, TimeUnit.SECONDS);
     55         } catch (Exception e) {
     56             logger.error("PUT cache exception [key=" + key + ", value=" + value + ", expire=" + expire + "].", e);
     57         }
     58     }
     59 
     60     /**
     61      * 获取缓存数据
     62      * 
     63      * @param key
     64      * @return
     65      */
     66     public Object getCache(String key) {
     67         try {
     68 
     69             return redisTemplate.opsForValue().get(key);
     70         } catch (Exception e) {
     71             logger.error("GET cache exception [key=" + key + "].", e);
     72         }
     73         return null;
     74     }
     75 
     76     /**
     77      * 删除缓存
     78      * 
     79      * @param key
     80      */
     81     public void removeCache(String key) {
     82         try {
     83 
     84             redisTemplate.delete(key);
     85 
     86         } catch (Exception e) {
     87             logger.error("Remove cache exception [key=" + key + "].", e);
     88         }
     89     }
     90 
     91     /******************************
     92      ********* 队列操作 ***********
     93      ******************************/
     94 
     95     /**
     96      * 队列缓存设置
     97      * 
     98      * @param key
     99      * @param value
    100      */
    101     public void putQueue(String key, Object value) {
    102         try {
    103 
    104             redisTemplate.opsForList().leftPush(key, value);
    105 
    106         } catch (Exception e) {
    107             logger.error("PUT Queue cache exception [key=" + key + ", value=" + value + "].", e);
    108         }
    109     }
    110 
    111     /**
    112      * 获取队列缓存
    113      * 
    114      * @param key
    115      * @return
    116      */
    117     public Object getQueue(String key) {
    118         try {
    119 
    120             return redisTemplate.opsForList().rightPop(key);
    121 
    122         } catch (Exception e) {
    123             logger.error("GET Queue cache exception [key=" + key + "].", e);
    124             return null;
    125         }
    126     }
    127 
    128     /******************************
    129      ********* 栈操作 ***********
    130      ******************************/
    131     public void putStack(String key, Object value) {
    132         try {
    133             redisTemplate.opsForList().leftPush(key, value);
    134         } catch (Exception e) {
    135             logger.error("PUT Stack cache exception [key=" + key + ", value=" + value + "].", e);
    136         }
    137     }
    138 
    139     public Object getStack(String key) {
    140         try {
    141             return redisTemplate.opsForList().leftPop(key);
    142 
    143         } catch (Exception e) {
    144             logger.error("GET Stack cache exception [key=" + key + "].", e);
    145             return null;
    146         }
    147     }
    148 
    149     public int length(String key) {
    150 
    151         try {
    152             return redisTemplate.opsForList().size(key).intValue();
    153         } catch (Exception e) {
    154             logger.error("GET cache length exception [key=" + key + "].", e);
    155             return 0;
    156         }
    157     }
    158 
    159     public void expire(String key, long timeout, TimeUnit unit) {
    160         try {
    161             redisTemplate.expire(key, timeout, unit);
    162         } catch (Exception e) {
    163             logger.error("SET expire time exception [key=" + key + "].", e);
    164         }
    165     }
    166 
    167     /******************************
    168      ********* hash操作 ***********
    169      ******************************/
    170     /**
    171      * hash put all
    172      * 
    173      * @param key
    174      * @param map
    175      * @date 2015年10月12日
    176      */
    177     public void hputs(String key, HashMap<? extends Object, ? extends Object> map) {
    178         try {
    179             redisTemplate.opsForHash().putAll(key, map);
    180         } catch (Exception e) {
    181             logger.error("PUT All Hash exception [key=" + key + "].", e);
    182         }
    183     }
    184 
    185     /**
    186      * hash put
    187      * 
    188      * @param key
    189      * @param hashKey
    190      * @param value
    191      * @date 2015年10月12日
    192      */
    193     public void hput(String key, Object hashKey, Object value) {
    194         try {
    195             redisTemplate.opsForHash().put(key, hashKey, value);
    196         } catch (Exception e) {
    197             logger.error("PUT Hash length exception [key=" + key + "].", e);
    198         }
    199     }
    200 
    201     /**
    202      * hash get
    203      * 
    204      * @param key
    205      * @param hashKey
    206      * @return
    207      * @date 2015年10月12日
    208      */
    209     public Object hget(String key, Object hashKey) {
    210         try {
    211             return redisTemplate.opsForHash().get(key, hashKey);
    212         } catch (Exception e) {
    213             logger.error("GET Hash exception [key=" + key + "].", e);
    214             return null;
    215         }
    216     }
    217 
    218     /**
    219      * hash remove
    220      * 
    221      * @param key
    222      * @param hashKey
    223      * @date 2015年10月12日
    224      */
    225     public void hrem(String key, Object hashKey) {
    226         try {
    227             redisTemplate.opsForHash().delete(key, hashKey);
    228         } catch (Exception e) {
    229             logger.error("DELETE Hash exception [key=" + key + "].", e);
    230         }
    231     }
    232 
    233     /**
    234      * hash size
    235      * 
    236      * @param key
    237      * @return
    238      * @date 2015年10月12日
    239      */
    240     public long hsize(String key) {
    241         try {
    242             return redisTemplate.opsForHash().size(key);
    243         } catch (Exception e) {
    244             logger.error("GET Hash size exception [key=" + key + "].", e);
    245             return 0;
    246         }
    247     }
    248     
    249     /**
    250      * hash keys
    251      * 
    252      * @param key
    253      * @return
    254      * @date 2015年10月12日
    255      */
    256     public Set<?> hkeys(String key) {
    257         try {
    258             return redisTemplate.opsForHash().keys(key);
    259         } catch (Exception e) {
    260             logger.error("GET Hash size exception [key=" + key + "].", e);
    261             return null;
    262         }
    263     }
    264     
    265     /**
    266      * 取出Map 
    267      */
    268     public Map<Object,Object> hMap(String key){
    269         try {
    270             return redisTemplate.opsForHash().entries(key);
    271         } catch (Exception e) {
    272             logger.error("GET Map size exception [key=" + key + "].", e);
    273             return null;
    274         }
    275     }
    276     
    277     
    278     /************************************************************
    279      **********************zset 操作***************************** 
    280      ************************************************************/
    281     /**
    282      *往Zset插入数据 
    283      */
    284     public void zsetPut(String key,Object hashKey,Double score){
    285         try{
    286             redisTemplate.opsForZSet().add(key, hashKey, score);
    287         }catch(Exception e){
    288             logger.error("PUT Zset exception [key=" + key + "].", e);
    289         }
    290     }
    291     
    292     /**
    293      * 查询Zset,按照开始结束score
    294      */
    295     public Set<?> zsetGet(String key,Double arg0,Double arg1){
    296         try{
    297             return redisTemplate.opsForZSet().rangeByScore(key, arg0, arg1);
    298         }catch(Exception e){
    299             logger.error("GET Zset exception [key=" + key + "].", e);
    300             return null;
    301         }
    302     }
    303     
    304     /**
    305      * 模糊查询 
    306      */
    307     public Set<String> fuzzyQuery(String pattern){
    308         try{
    309             return redisTemplate.keys(pattern);
    310         }catch(Exception e){
    311             logger.error("GET fuzzyQuery exception [key=" + pattern + "].", e);
    312             return null;
    313         }
    314     }
    315     
    316     public RedisTemplate<String, Object> getRedisTemplate() {
    317         return redisTemplate;
    318     }
    319 
    320     public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
    321         this.redisTemplate = redisTemplate;
    322     }
    323 }
    CacheService.java类文件

    我们使用快捷键:ctrl+o迅速浏览一下CacheService.java类文件中的方法:

    其中有如下的方法:用于设置缓存。

     1     /**
     2      * 设置缓存
     3      * 
     4      * @param key
     5      * @param value
     6      */
     7     public void putCache(String key, Object value) {
     8         try {
     9             redisTemplate.opsForValue().set(key, value);
    10         } catch (Exception e) {
    11             logger.error("PUT cache exception [key=" + key + ", value=" + value + "].", e);
    12         }
    13     }
    设置缓存

    做好了上述配置,再来看看我们项目中是如何使用他们的。

     1     public TradingArea findById(Integer id) {
     2         if (id == null)
     3             return null;
     4         TradingArea ta = tradingAreaMapper.selectByPrimaryKey(id);
     5         if (ta == null || ta.getIsActive() == (byte) 0) {
     6             return null;
     7         }
     8         return ta;
     9     }
    10     
    11     
    12     /**
    13      * @Description: 缓存数据查询
    14      */
    15     @Cache(expire = CacheService.EXPIRE_TIME_HALFDAY)
    16     public TradingArea getTradingArea(Integer id){
    17         return findById(id);
    18     }
    两个方法

    根据主键ID查找对应的对象,我们写了两个方法,其中第一个方法,是针对该对象的增删改查,所以必须要用到实时数据,不能使用缓存。第二个方法,很显然,上方添加了缓存注解,通过设置缓存的有效时间,我们凡是做为关联表来查询的时候,都可以使用缓存来提示效率。那么问题的核心来了,我们上方添加了一个有效时间的注解,项目中是怎么实现来帮助我们取缓存的呢?先看缓存的定义文件

    1 @Target(ElementType.METHOD)
    2 @Retention(RetentionPolicy.RUNTIME)
    3 public @interface Cache {
    4     boolean notCacheNull() default false;
    5     int expire() default CacheService.EXPIRE_TIME_ONEDAY ;
    6     boolean requireNew() default false;
    7 }

    当上述注解加在方法上的时候,会被一个拦截器拦截,拦截器拦截到之后,就会执行我们想要让缓存来做的:有就取出,没有就查SQL,同时拷贝一份在缓存中。下述是拦截器的配置文件,如下:

    1     <bean id="businessMethodInterceptor" class="com.XX.XX.interceptor.BusinessMethodInterceptor">
    2         <property name="needRoutingDatasource" value="false" />
    3     </bean>

    我们来看一下拦截器,拦截了缓存注解之后,有哪些操作,代码如下:

     1        /**
     2          * 缓存处理
     3          */
     4         if (thisMethod.isAnnotationPresent(Cache.class)) {
     5             Cache annotation = thisMethod.getAnnotation(Cache.class);
     6             Class<?> returnType = thisMethod.getReturnType();
     7             if (returnType != null && !"void".equals(returnType.getName())) {
     8                 Object cache = null;
     9                 try {
    10                     CacheKey key = new CacheKey(thisMethod.getDeclaringClass(), thisMethod, invocation.getArguments());
    11                     if(!annotation.requireNew()){
    12                         cache = cacheService.getCache(key.toString());
    14                     }
    15                     if (cache == null) {
    16                         cache = invocation.proceed();
    17                         try {
    18                             cacheService.putCache(key.toString(), cache, annotation.expire());
    19                         } catch (Exception e) {
    20                             logger.error("Cache Annotation process PUT CACHE exception.", e);
    21                         }
    23                     }
    24                     return cache;
    25                 } catch (Exception e) {
    26                     logger.error("Cache Annotation process exception.", e);
    27                 }
    28             }
    29         }
    30         return invocation.proceed();
  • 相关阅读:
    【NOI2005T4】聪聪和可可-期望DP+记忆化搜索
    总结:最大权闭合子图
    【NOI2009T4】植物大战僵尸-最大权闭合子图+拓补排序
    codevs 1090 加分二叉树
    codevs 1503 愚蠢的宠物
    codevs 1992 聚会
    welcome to new life
    codevs 1066 引水入城
    codevs 2021 中庸之道
    POJ 2104 K-th Number
  • 原文地址:https://www.cnblogs.com/RunForLove/p/4903734.html
Copyright © 2011-2022 走看看