日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Redis整合Spring結(jié)合使用緩存實(shí)例

一、Redis介紹

專注于為中小企業(yè)提供成都做網(wǎng)站、成都網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)康樂(lè)免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了近1000家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

什么是Redis?

redis是一個(gè)key-value存儲(chǔ)系統(tǒng)。和Memcached類似,它支持存儲(chǔ)的value類型相對(duì)更多,包括string(字符串)、 list(鏈表)、set(集合)、zset(sorted set –有序集合)和hash(哈希類型)。這些數(shù)據(jù)類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原 子性的。在此基礎(chǔ)上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是redis會(huì)周期性的 把更新的數(shù)據(jù)寫(xiě)入磁盤(pán)或者把修改操作寫(xiě)入追加的記錄文件,并且在此基礎(chǔ)上實(shí)現(xiàn)了master-slave(主從)同步。

它有什么特點(diǎn)?

(1)Redis數(shù)據(jù)庫(kù)完全在內(nèi)存中,使用磁盤(pán)僅用于持久性。
(2)相比許多鍵值數(shù)據(jù)存儲(chǔ),Redis擁有一套較為豐富的數(shù)據(jù)類型。
(3)Redis可以將數(shù)據(jù)復(fù)制到任意數(shù)量的從服務(wù)器。

Redis 優(yōu)勢(shì)?

(1)異??焖伲篟edis的速度非常快,每秒能執(zhí)行約11萬(wàn)集合,每秒約81000+條記錄。
(2)支持豐富的數(shù)據(jù)類型:Redis支持***多數(shù)開(kāi)發(fā)人員已經(jīng)知道像列表,集合,有序集合,散列數(shù)據(jù)類型。這使得它非常容易解決各種各樣的問(wèn)題,因?yàn)槲覀冎滥男﹩?wèn)題是可以處理通過(guò)它的數(shù)據(jù)類型更好。
(3)操作都是原子性:所有Redis操作是原子的,這保證了如果兩個(gè)客戶端同時(shí)訪問(wèn)的Redis服務(wù)器將獲得更新后的值。
(4)多功能實(shí)用工具:Redis是一個(gè)多實(shí)用的工具,可以在多個(gè)用例如緩存,消息,隊(duì)列使用(Redis原生支持發(fā)布/訂閱),任何短暫的數(shù)據(jù),應(yīng)用程序,如Web應(yīng)用程序會(huì)話,網(wǎng)頁(yè)***計(jì)數(shù)等。

Redis 缺點(diǎn)?

(1)單線程

(2)耗內(nèi)存

二、使用實(shí)例

本文使用maven+eclipse+sping

1、引入jar包

 
 
 
 
  1.      
  2.  
  3.  org.springframework.data 
  4.  spring-data-redis 
  5.  1.6.1.RELEASE 
  6.  
  7.  
  8.  redis.clients 
  9.  jedis 
  10.  2.7.3 
  11.  
  12.     

2、配置bean

在application.xml加入如下配置

 
 
 
 
  1.  
  2.      
  3.            
  4.            
  5.            
  6.      
  7.     
  8.      
  9.            
  10.            
  11.            
  12.            
  13.            
  14.      
  15.      
  16.            
  17.            
  18.                
  19.            
  20.            
  21.                
  22.            
  23.      
  24.  
  25.       
  26.      
  27.            
  28.      
  29.      
  30.            
  31.      

其中配置文件redis一些配置數(shù)據(jù)redis.properties如下:

 
 
 
 
  1. #redis中心 
  2. redis.host=10.75.202.11 
  3. redis.port=6379 
  4. redis.password=123456 
  5. redis.maxIdle=100 
  6. redis.maxActive=300 
  7. redis.maxWait=1000 
  8. redis.testOnBorrow=true 
  9. redis.timeout=100000 
  10.  
  11. # 不需要加入緩存的類 
  12. targetNames=xxxRecordManager,xxxSetRecordManager,xxxStatisticsIdentificationManager 
  13. # 不需要緩存的方法 
  14. methodNames= 
  15.  
  16. #設(shè)置緩存失效時(shí)間 
  17. com.service.impl.xxxRecordManager= 60 
  18. com.service.impl.xxxSetRecordManager= 60 
  19. defaultCacheExpireTime=3600 
  20.  
  21. fep.local.cache.capacity =10000 

要掃這些properties文件,在application.xml加入如下配置

 
 
 
 
  1.    
  2.   
  3.      
  4.          
  5.            classpath:properties/*.properties 
  6.              
  7.          
  8.      
  9.  

3、一些工具類

(1)RedisUtil

上面的bean中,RedisUtil是用來(lái)緩存和去除數(shù)據(jù)的實(shí)例

 
 
 
 
  1. package com.mucfc.msm.common; 
  2.  
  3. import java.io.Serializable; 
  4. import java.util.Set; 
  5. import java.util.concurrent.TimeUnit; 
  6.  
  7. import org.apache.log4j.Logger; 
  8. import org.springframework.data.redis.core.RedisTemplate; 
  9. import org.springframework.data.redis.core.ValueOperations; 
  10.  
  11. /** 
  12. * redis cache 工具類 
  13. */ 
  14. public final class RedisUtil { 
  15. private Logger logger = Logger.getLogger(RedisUtil.class); 
  16. private RedisTemplate redisTemplate; 
  17.  
  18. /** 
  19.   * 批量刪除對(duì)應(yīng)的value 
  20.   * 
  21.   * @param keys 
  22.   */ 
  23. public void remove(final String... keys) { 
  24.   for (String key : keys) { 
  25.    remove(key); 
  26.   } 
  27.  
  28. /** 
  29.   * 批量刪除key 
  30.   * 
  31.   * @param pattern 
  32.   */ 
  33. public void removePattern(final String pattern) { 
  34.   Set keys = redisTemplate.keys(pattern); 
  35.   if (keys.size() > 0) 
  36.    redisTemplate.delete(keys); 
  37.  
  38. /** 
  39.   * 刪除對(duì)應(yīng)的value 
  40.   * 
  41.   * @param key 
  42.   */ 
  43. public void remove(final String key) { 
  44.   if (exists(key)) { 
  45.    redisTemplate.delete(key); 
  46.   } 
  47.  
  48. /** 
  49.   * 判斷緩存中是否有對(duì)應(yīng)的value 
  50.   * 
  51.   * @param key 
  52.   * @return 
  53.   */ 
  54. public boolean exists(final String key) { 
  55.   return redisTemplate.hasKey(key); 
  56.  
  57. /** 
  58.   * 讀取緩存 
  59.   * 
  60.   * @param key 
  61.   * @return 
  62.   */ 
  63. public Object get(final String key) { 
  64.   Object result = null; 
  65.   ValueOperations operations = redisTemplate 
  66.     .opsForValue(); 
  67.   result = operations.get(key); 
  68.   return result; 
  69.  
  70. /** 
  71.   * 寫(xiě)入緩存 
  72.   * 
  73.   * @param key 
  74.   * @param value 
  75.   * @return 
  76.   */ 
  77. public boolean set(final String key, Object value) { 
  78.   boolean result = false; 
  79.   try { 
  80.    ValueOperations operations = redisTemplate 
  81.      .opsForValue(); 
  82.    operations.set(key, value); 
  83.    result = true; 
  84.   } catch (Exception e) { 
  85.    e.printStackTrace(); 
  86.   } 
  87.   return result; 
  88.  
  89. /** 
  90.   * 寫(xiě)入緩存 
  91.   * 
  92.   * @param key 
  93.   * @param value 
  94.   * @return 
  95.   */ 
  96. public boolean set(final String key, Object value, Long expireTime) { 
  97.   boolean result = false; 
  98.   try { 
  99.    ValueOperations operations = redisTemplate 
  100.      .opsForValue(); 
  101.    operations.set(key, value); 
  102.    redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); 
  103.    result = true; 
  104.   } catch (Exception e) { 
  105.    e.printStackTrace(); 
  106.   } 
  107.   return result; 
  108.  
  109. public void setRedisTemplate( 
  110.    RedisTemplate redisTemplate) { 
  111.   this.redisTemplate = redisTemplate; 

(2)MethodCacheInterceptor

切面MethodCacheInterceptor,這是用來(lái)給不同的方法來(lái)加入判斷如果緩存存在數(shù)據(jù),從緩存取數(shù)據(jù)。否則***次從數(shù)據(jù)庫(kù)取,并將結(jié)果保存到緩存 中去。

 
 
 
 
  1. package com.mucfc.msm.common; 
  2.  
  3. import java.io.File; 
  4. import java.io.FileInputStream; 
  5. import java.io.InputStream; 
  6. import java.util.ArrayList; 
  7. import java.util.List; 
  8. import java.util.Properties; 
  9.  
  10. import org.aopalliance.intercept.MethodInterceptor; 
  11. import org.aopalliance.intercept.MethodInvocation; 
  12. import org.apache.log4j.Logger; 
  13.  
  14. public class MethodCacheInterceptor implements MethodInterceptor { 
  15. private Logger logger = Logger.getLogger(MethodCacheInterceptor.class); 
  16. private RedisUtil redisUtil; 
  17. private List targetNamesList; // 不加入緩存的service名稱 
  18. private List methodNamesList; // 不加入緩存的方法名稱 
  19. private Long defaultCacheExpireTime; // 緩存默認(rèn)的過(guò)期時(shí)間 
  20. private Long xxxRecordManagerTime; // 
  21. private Long xxxSetRecordManagerTime; // 
  22.  
  23. /** 
  24.   * 初始化讀取不需要加入緩存的類名和方法名稱 
  25.   */ 
  26. public MethodCacheInterceptor() { 
  27.   try { 
  28.     File f = new File("D:\\lunaJee-workspace\\msm\\msm_core\\src\\main\\java\\com\\mucfc\\msm\\common\\cacheConf.properties"); 
  29.     //配置文件位置直接被寫(xiě)死,有需要自己修改下 
  30.        InputStream in = new FileInputStream(f); 
  31. //   InputStream in = getClass().getClassLoader().getResourceAsStream( 
  32. //     "D:\\lunaJee-workspace\\msm\\msm_core\\src\\main\\java\\com\\mucfc\\msm\\common\\cacheConf.properties"); 
  33.    Properties p = new Properties(); 
  34.    p.load(in); 
  35.    // 分割字符串 
  36.    String[] targetNames = p.getProperty("targetNames").split(","); 
  37.    String[] methodNames = p.getProperty("methodNames").split(","); 
  38.  
  39.    // 加載過(guò)期時(shí)間設(shè)置 
  40.    defaultCacheExpireTime = Long.valueOf(p.getProperty("defaultCacheExpireTime")); 
  41.    xxxRecordManagerTime = Long.valueOf(p.getProperty("com.service.impl.xxxRecordManager")); 
  42.    xxxSetRecordManagerTime = Long.valueOf(p.getProperty("com.service.impl.xxxSetRecordManager")); 
  43.    // 創(chuàng)建list 
  44.    targetNamesList = new ArrayList(targetNames.length); 
  45.    methodNamesList = new ArrayList(methodNames.length); 
  46.    Integer maxLen = targetNames.length > methodNames.length ? targetNames.length 
  47.      : methodNames.length; 
  48.    // 將不需要緩存的類名和方法名添加到list中 
  49.    for (int i = 0; i < maxLen; i++) { 
  50.     if (i < targetNames.length) { 
  51.      targetNamesList.add(targetNames[i]); 
  52.     } 
  53.     if (i < methodNames.length) { 
  54.      methodNamesList.add(methodNames[i]); 
  55.     } 
  56.    } 
  57.   } catch (Exception e) { 
  58.    e.printStackTrace(); 
  59.   } 
  60.  
  61. @Override 
  62. public Object invoke(MethodInvocation invocation) throws Throwable { 
  63.   Object value = null; 
  64.  
  65.   String targetName = invocation.getThis().getClass().getName(); 
  66.   String methodName = invocation.getMethod().getName(); 
  67.   // 不需要緩存的內(nèi)容 
  68.   //if (!isAddCache(StringUtil.subStrForLastDot(targetName), methodName)) { 
  69.   if (!isAddCache(targetName, methodName)) { 
  70.    // 執(zhí)行方法返回結(jié)果 
  71.    return invocation.proceed(); 
  72.   } 
  73.   Object[] arguments = invocation.getArguments(); 
  74.   String key = getCacheKey(targetName, methodName, arguments); 
  75.   System.out.println(key); 
  76.  
  77.   try { 
  78.    // 判斷是否有緩存 
  79.    if (redisUtil.exists(key)) { 
  80.     return redisUtil.get(key); 
  81.    } 
  82.    // 寫(xiě)入緩存 
  83.    value = invocation.proceed(); 
  84.    if (value != null) { 
  85.     final String tkey = key; 
  86.     final Object tvalue = value; 
  87.     new Thread(new Runnable() { 
  88.      @Override 
  89.      public void run() { 
  90.       if (tkey.startsWith("com.service.impl.xxxRecordManager")) { 
  91.        redisUtil.set(tkey, tvalue, xxxRecordManagerTime); 
  92.       } else if (tkey.startsWith("com.service.impl.xxxSetRecordManager")) { 
  93.        redisUtil.set(tkey, tvalue, xxxSetRecordManagerTime); 
  94.       } else { 
  95.        redisUtil.set(tkey, tvalue, defaultCacheExpireTime); 
  96.       } 
  97.      } 
  98.     }).start(); 
  99.    } 
  100.   } catch (Exception e) { 
  101.    e.printStackTrace(); 
  102.    if (value == null) { 
  103.     return invocation.proceed(); 
  104.    } 
  105.   } 
  106.   return value; 
  107.  
  108. /** 
  109.   * 是否加入緩存 
  110.   * 
  111.   * @return 
  112.   */ 
  113. private boolean isAddCache(String targetName, String methodName) { 
  114.   boolean flag = true; 
  115.   if (targetNamesList.contains(targetName) 
  116.     || methodNamesList.contains(methodName)) { 
  117.    flag = false; 
  118.   } 
  119.   return flag; 
  120.  
  121. /** 
  122.   * 創(chuàng)建緩存key 
  123.   * 
  124.   * @param targetName 
  125.   * @param methodName 
  126.   * @param arguments 
  127.   */ 
  128. private String getCacheKey(String targetName, String methodName, 
  129.    Object[] arguments) { 
  130.   StringBuffer sbu = new StringBuffer(); 
  131.   sbu.append(targetName).append("_").append(methodName); 
  132.   if ((arguments != null) && (arguments.length != 0)) { 
  133.    for (int i = 0; i < arguments.length; i++) { 
  134.     sbu.append("_").append(arguments[i]); 
  135.    } 
  136.   } 
  137.   return sbu.toString(); 
  138.  
  139. public void setRedisUtil(RedisUtil redisUtil) { 
  140.   this.redisUtil = redisUtil; 

4、配置需要緩存的類或方法

在application.xml加入如下配置,有多個(gè)類或方法可以配置多個(gè)

 
 
 
 
  1.  
  2.  
  3.        
  4.            
  5.        
  6.        
  7.            
  8.             
  9.              com\.mucfc\.msm\.service\.impl\...*ServiceImpl.* 
  10.            
  11.        
  12.  

5、執(zhí)行結(jié)果:

寫(xiě)了一個(gè)簡(jiǎn)單的單元測(cè)試如下:

 
 
 
 
  1. @Test 
  2.  public void getSettUnitBySettUnitIdTest() { 
  3.      String systemId = "CES"; 
  4.      String merchantId = "133"; 
  5.      SettUnit configSettUnit = settUnitService.getSettUnitBySettUnitId(systemId, merchantId, "ESP"); 
  6.      SettUnit configSettUnit1 = settUnitService.getSettUnitBySettUnitId(systemId, merchantId, "ESP"); 
  7.      boolean flag= (configSettUnit == configSettUnit1); 
  8.      System.out.println(configSettUnit); 
  9.      logger.info("查找結(jié)果" + configSettUnit.getBusinessType()); 
  10.  
  11.    //  localSecondFIFOCache.put("configSettUnit", configSettUnit.getBusinessType()); 
  12.   //  String string = localSecondFIFOCache.get("configSettUnit"); 
  13.        logger.info("查找結(jié)果" + string); 
  14.  } 

這是***次執(zhí)行單元測(cè)試的過(guò)程:

MethodCacheInterceptor這個(gè)類中打了斷點(diǎn),然后每次查詢前都會(huì)先進(jìn)入這個(gè)方法

依次運(yùn)行,發(fā)現(xiàn)沒(méi)有緩存,所以會(huì)直接去查數(shù)據(jù)庫(kù)

打印了出來(lái)的SQL語(yǔ)句:

第二次執(zhí)行:

因?yàn)?**次執(zhí)行時(shí),已經(jīng)寫(xiě)入緩存了。所以第二次直接從緩存中取數(shù)據(jù)

3、取兩次的結(jié)果進(jìn)行地址的對(duì)比:

發(fā)現(xiàn)兩個(gè)不是同一個(gè)對(duì)象,沒(méi)錯(cuò),是對(duì)的。如果是使用Ehcache的 話,那么二者的內(nèi)存地址會(huì)是一樣的。那是因?yàn)閞edis和ehcache使用的緩存機(jī)制是不一樣的。ehcache是基于本地電腦的內(nèi)存使用緩存,所以使 用緩存取數(shù)據(jù)時(shí)直接在本地電腦上取。轉(zhuǎn)換成java對(duì)象就會(huì)是同一個(gè)內(nèi)存地址,而redis它是在裝有redis服務(wù)的電腦上(一般是另一臺(tái)電腦),所以 取數(shù)據(jù)時(shí)經(jīng)過(guò)傳輸?shù)奖镜?,?huì)對(duì)應(yīng)到不同的內(nèi)存地址,所以用==來(lái)比較會(huì)返回false。但是它確實(shí)是從緩存中去取的,這點(diǎn)我們從上面的斷點(diǎn)可以看到。

 
 


網(wǎng)站題目:Redis整合Spring結(jié)合使用緩存實(shí)例
轉(zhuǎn)載來(lái)于:http://www.5511xx.com/article/dphssgg.html