spring + redis 實現數據的緩存 阿新 • • 發佈:2017-06-26 ide obj ppi final toa apache ins 城市 del 1、實現目標 通過redis緩存數據。(目的不是加快查詢的速度,而是減少數據庫的負擔) 2、所需jar包 註意:jdies和commons-pool兩個jar的版本是有對應關系的,註意引入jar包是要配對使用,否則將會報錯。因為commons-pooljar的目錄根據版本的變化,目錄結構會變。前面的版本是org.apache.pool,而後面的版本是org.apache.pool2… style=” color: white; font-size: 17px; font-weight: bold;”3、redis簡介 redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set –有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從) 4、編碼實現 1)、配置的文件(properties) 將那些經常要變化的參數配置成獨立的propertis,方便以後的修改 redis.properties redis.hostName=127.0.0.1 redis.port=6379 redis.timeout=15000 redis.usePool=true redis.maxIdle=6 redis.minEvictableIdleTimeMillis=300000 redis.numTestsPerEvictionRun=3 redis.timeBetweenEvictionRunsMillis=60000 2)、spring-redis.xml redis的相關參數配置設置。參數的值來自上面的properties文件 <beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"default-autowire="byName"> <beanid="jedisPoolConfig"class="redis.clients.jedis.JedisPoolConfig"> <propertyname="maxIdle"value="${redis.maxIdle}">property> <propertyname="minEvictableIdleTimeMillis"value="${redis.minEvictableIdleTimeMillis}">property> <propertyname="numTestsPerEvictionRun"value="${redis.numTestsPerEvictionRun}">property> <propertyname="timeBetweenEvictionRunsMillis"value="${redis.timeBetweenEvictionRunsMillis}">property> bean> <beanid="jedisConnectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"destroy-method="destroy"> <propertyname="poolConfig"ref="jedisPoolConfig">property> <propertyname="hostName"value="${redis.hostName}">property> <propertyname="port"value="${redis.port}">property> <propertyname="timeout"value="${redis.timeout}">property> <propertyname="usePool"value="${redis.usePool}">property> bean> <beanid="jedisTemplate"class="org.springframework.data.redis.core.RedisTemplate"> <propertyname="connectionFactory"ref="jedisConnectionFactory">property> <propertyname="keySerializer"> <beanclass="org.springframework.data.redis.serializer.StringRedisSerializer"/> property> <propertyname="valueSerializer"> <beanclass="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/> property> bean> beans> 3)、applicationContext.xml spring的總配置文件,在裏面假如一下的代碼 <beanclass="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <propertyname="systemPropertiesModeName"value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/> <propertyname="ignoreResourceNotFound"value="true"/> <propertyname="locations"> <list> <value>classpath*:/META-INF/config/redis.propertiesvalue> list> property> bean> <importresource="spring-redis.xml"/> 4)、web。xml 設置spring的總配置文件在項目啟動時加載 <context-param> <param-name>contextConfigLocationparam-name> <param-value>classpath*:/META-INF/applicationContext.xmlparam-value> context-param> 5)、redis緩存工具類 ValueOperations ——基本數據類型和實體類的緩存 ListOperations ——list的緩存 SetOperations ——set的緩存 HashOperations Map的緩存 importjava.io.Serializable; importjava.util.ArrayList; importjava.util.HashMap; importjava.util.HashSet; importjava.util.Iterator; importjava.util.List; importjava.util.Map; importjava.util.Set; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.beans.factory.annotation.Qualifier; importorg.springframework.context.support.ClassPathXmlApplicationContext; importorg.springframework.data.redis.core.BoundSetOperations; importorg.springframework.data.redis.core.HashOperations; importorg.springframework.data.redis.core.ListOperations; importorg.springframework.data.redis.core.RedisTemplate; importorg.springframework.data.redis.core.SetOperations; importorg.springframework.data.redis.core.ValueOperations; importorg.springframework.stereotype.Service; @Service publicclassRedisCacheUtil { @[email protected]/* */("jedisTemplate") publicRedisTemplate redisTemplate; /** * 緩存基本的對象,Integer、String、實體類等 * @param key 緩存的鍵值 * @param value 緩存的值 * @return 緩存的對象 */ public ValueOperations setCacheObject(String key,T value) { ValueOperations operation = redisTemplate.opsForValue(); operation.set(key,value); returnoperation; } /** * 獲得緩存的基本對象。 * @param key 緩存鍵值 * @param operation * @return 緩存鍵值對應的數據 */ public T getCacheObject(String key/*,ValueOperations operation*/) { ValueOperations operation = redisTemplate.opsForValue(); return operation.get(key); } /** * 緩存List數據 * @param key 緩存的鍵值 * @param dataList 待緩存的List數據 * @return 緩存的對象 */ public ListOperations setCacheList(String key,List dataList) { ListOperations listOperation = redisTemplate.opsForList(); if(null != dataList) { int size = dataList.size(); for(int i = 0; i < size ; i ++) { listOperation.rightPush(key,dataList.get(i)); } } return listOperation; } /** * 獲得緩存的list對象 * @param key 緩存的鍵值 * @return 緩存鍵值對應的數據 */ public List getCacheList(String key) { List dataList = new ArrayList(); ListOperations listOperation = redisTemplate.opsForList(); Long size = listOperation.size(key); for(int i = 0 ; i < size ; i ++) { dataList.add((T) listOperation.leftPop(key)); } return dataList; } /** * 緩存Set * @param key 緩存鍵值 * @param dataSet 緩存的數據 * @return 緩存數據的對象 */ public BoundSetOperations setCacheSet(String key,Set dataSet) { BoundSetOperations setOperation = redisTemplate.boundSetOps(key); /*T[] t = (T[]) dataSet.toArray(); setOperation.add(t);*/ Iterator it = dataSet.iterator(); while(it.hasNext()) { setOperation.add(it.next()); } return setOperation; } /** * 獲得緩存的set * @param key * @param operation * @return */ public Set getCacheSet(String key/*,BoundSetOperations operation*/) { Set dataSet = new HashSet(); BoundSetOperations operation = redisTemplate.boundSetOps(key); Long size = operation.size(); for(int i = 0 ; i < size ; i++) { dataSet.add(operation.pop()); } return dataSet; } /** * 緩存Map * @param key * @param dataMap * @return */ public HashOperations setCacheMap(String key,Map dataMap) { HashOperations hashOperations = redisTemplate.opsForHash(); if(null != dataMap) { for (Map.Entry entry : dataMap.entrySet()) { /*System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); */ hashOperations.put(key,entry.getKey(),entry.getValue()); } } return hashOperations; } /** * 獲得緩存的Map * @param key * @param hashOperation * @return */ public Map getCacheMap(String key/*,HashOperations hashOperation*/) { Map map = redisTemplate.opsForHash().entries(key); /*Map map = hashOperation.entries(key);*/ return map; } /** * 緩存Map * @param key * @param dataMap * @return */ public HashOperations setCacheIntegerMap(String key,Map dataMap) { HashOperations hashOperations = redisTemplate.opsForHash(); if(null != dataMap) { for (Map.Entry entry : dataMap.entrySet()) { /*System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); */ hashOperations.put(key,entry.getKey(),entry.getValue()); } } return hashOperations; } /** * 獲得緩存的Map * @param key * @param hashOperation * @return */ public Map getCacheIntegerMap(String key/*,HashOperations hashOperation*/) { Map map = redisTemplate.opsForHash().entries(key); /*Map map = hashOperation.entries(key);*/ returnmap; } } 6)、測試 這裏測試我是在項目啟動的時候到數據庫中查找出國家和城市的數據,進行緩存,之後將數據去出 6.1 項目啟動時緩存數據 importjava.util.HashMap; importjava.util.List; importjava.util.Map; importorg.apache.log4j.Logger; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.context.ApplicationListener; importorg.springframework.context.event.ContextRefreshedEvent; importorg.springframework.stereotype.Service; importcom.test.model.City; importcom.test.model.Country; importcom.zcr.test.User; /* * 監聽器,用於項目啟動的時候初始化信息 */ @Service publicclassStartAddCacheListener implementsApplicationListener { //日誌 privatefinalLogger log= Logger.getLogger(StartAddCacheListener.class); @Autowired privateRedisCacheUtil redisCache; @Autowired privateBrandStoreService brandStoreService; @Override publicvoidonApplicationEvent(ContextRefreshedEvent event) { //spring 啟動的時候緩存城市和國家等信息 if(event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext")) { System.out.println("\n\n\n_________\n\n緩存數據 \n\n ________\n\n\n\n"); List cityList = brandStoreService.selectAllCityMessage(); List countryList = brandStoreService.selectAllCountryMessage(); Map cityMap = newHashMap(); Map countryMap = newHashMap(); intcityListSize = cityList.size(); intcountryListSize = countryList.size(); for(inti = 0; i < cityListSize ; i ++ ) { cityMap.put(cityList.get(i).getCity_id(), cityList.get(i)); } for(inti = 0; i < countryListSize ; i ++ ) { countryMap.put(countryList.get(i).getCountry_id(), countryList.get(i)); } redisCache.setCacheIntegerMap("cityMap", cityMap); redisCache.setCacheIntegerMap("countryMap", countryMap); } } } 6.2 獲取緩存數據 @Autowired privateRedisCacheUtil redisCache; @RequestMapping("testGetCache") publicvoidtestGetCache() { /*Map countryMap = redisCacheUtil1.getCacheMap("country"); Map cityMap = redisCacheUtil.getCacheMap("city");*/ Map countryMap = redisCacheUtil1.getCacheIntegerMap("countryMap"); Map cityMap = redisCacheUtil.getCacheIntegerMap("cityMap"); for(intkey : countryMap.keySet()) { System.out.println("key = "+ key + ",value="+ countryMap.get(key)); } System.out.println("------------city"); for(intkey : cityMap.keySet()) { System.out.println("key = "+ key + ",value="+ cityMap.get(key)); } } 由於Spring在配置文件中配置的bean默認是單例的,所以只需要通過Autowired註入,即可得到原先的緩存類。spring + redis 實現數據的緩存