redis與spring的整合(使用緩存)

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(主從)

3、編碼實現

1)、配置的文件(properties)

  將那些經常要變化的參數配置成獨立的propertis,方便以後的修改redis.properties

1

2

3

4

5

6

7

8

9

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文件

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

<beans xmlns="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">

 <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">

  <!-- <property name="maxIdle" value="6"></property>

  <property name="minEvictableIdleTimeMillis" value="300000"></property>

  <property name="numTestsPerEvictionRun" value="3"></property>

  <property name="timeBetweenEvictionRunsMillis" value="60000"></property> -->

   

  <property name="maxIdle" value="${redis.maxIdle}"></property>

  <property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}"></property>

  <property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}"></property>

  <property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}"></property>

 </bean>

 <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">

  <property name="poolConfig" ref="jedisPoolConfig"></property>

  <property name="hostName" value="${redis.hostName}"></property>

  <property name="port" value="${redis.port}"></property>

  <property name="timeout" value="${redis.timeout}"></property>

  <property name="usePool" value="${redis.usePool}"></property>

 </bean>

 <bean id="jedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">

  <property name="connectionFactory" ref="jedisConnectionFactory"></property>

  <property name="keySerializer">

   <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

  </property>

  <property name="valueSerializer">

   <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>

  </property>

 </bean>

</beans>

3)、applicationContext.xml

  spring的總配置文件,在裏面假如一下的代碼

1

2

3

4

5

6

7

8

9

10

11

12

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

  <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />

  <property name="ignoreResourceNotFound" value="true" />

  <property name="locations">

   <list>

     

    <value>classpath*:/META-INF/config/redis.properties</value>

   </list>

  </property>

 </bean>

 

<import resource="spring-redis.xml" />

4)、web.xml

  設置spring的總配置文件在項目啓動時加載

1

2

3

4

<context-param>

 <param-name>contextConfigLocation</param-name>

 <param-value>classpath*:/META-INF/applicationContext.xml</param-value><!-- -->

</context-param>

5)、redis緩存工具類

ValueOperations  ——基本數據類型和實體類的緩存
ListOperations     ——list的緩存
SetOperations    ——set的緩存

HashOperations  Map的緩存

 

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

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

import java.io.Serializable;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Set;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import org.springframework.data.redis.core.BoundSetOperations;

import org.springframework.data.redis.core.HashOperations;

import org.springframework.data.redis.core.ListOperations;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.core.SetOperations;

import org.springframework.data.redis.core.ValueOperations;

import org.springframework.stereotype.Service;

 

@Service

public class RedisCacheUtil<T>

{

 

  

 @Autowired @Qualifier("jedisTemplate")

 public RedisTemplate redisTemplate;

  

 

  

 /**

  * 緩存基本的對象,Integer、String、實體類等

  * @param key 緩存的鍵值

  * @param value 緩存的值

  * @return  緩存的對象

  */

 public <T> ValueOperations<String,T> setCacheObject(String key,T value)

 {

   

  ValueOperations<String,T> operation = redisTemplate.opsForValue();

  operation.set(key,value);

  return operation;

 }

  

 /**

  * 獲得緩存的基本對象。

  * @param key  緩存鍵值

  * @param operation

  * @return   緩存鍵值對應的數據

  */

 public <T> T getCacheObject(String key/*,ValueOperations<String,T> operation*/)

 {

  ValueOperations<String,T> operation = redisTemplate.opsForValue();

  return operation.get(key);

 }

  

 /**

  * 緩存List數據

  * @param key  緩存的鍵值

  * @param dataList 待緩存的List數據

  * @return   緩存的對象

  */

 public <T> ListOperations<String, T> setCacheList(String key,List<T> 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 <T> List<T> getCacheList(String key)

 {

  List<T> dataList = new ArrayList<T>();

  ListOperations<String,T> 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 <T> BoundSetOperations<String,T> setCacheSet(String key,Set<T> dataSet)

 {

  BoundSetOperations<String,T> setOperation = redisTemplate.boundSetOps(key);

  /*T[] t = (T[]) dataSet.toArray();

    setOperation.add(t);*/

   

   

  Iterator<T> it = dataSet.iterator();

  while(it.hasNext())

  {

   setOperation.add(it.next());

  }

   

  return setOperation;

 }

  

 /**

  * 獲得緩存的set

  * @param key

  * @param operation

  * @return

  */

 public Set<T> getCacheSet(String key/*,BoundSetOperations<String,T> operation*/)

 {

  Set<T> dataSet = new HashSet<T>();

  BoundSetOperations<String,T> 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 <T> HashOperations<String,String,T> setCacheMap(String key,Map<String,T> dataMap)

 {

   

  HashOperations hashOperations = redisTemplate.opsForHash();

  if(null != dataMap)

  {

    

   for (Map.Entry<String, T> 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 <T> Map<String,T> getCacheMap(String key/*,HashOperations<String,String,T> hashOperation*/)

 {

  Map<String, T> map = redisTemplate.opsForHash().entries(key);

  /*Map<String, T> map = hashOperation.entries(key);*/

  return map;

 }

  

  

  

  

  

  

  

 /**

  * 緩存Map

  * @param key

  * @param dataMap

  * @return

  */

 public <T> HashOperations<String,Integer,T> setCacheIntegerMap(String key,Map<Integer,T> dataMap)

 {

  HashOperations hashOperations = redisTemplate.opsForHash();

  if(null != dataMap)

  {

    

   for (Map.Entry<Integer, T> 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 <T> Map<Integer,T> getCacheIntegerMap(String key/*,HashOperations<String,String,T> hashOperation*/)

 {

  Map<Integer, T> map = redisTemplate.opsForHash().entries(key);

  /*Map<String, T> map = hashOperation.entries(key);*/

  return map;

 }

}

6)、測試

  這裏測試我是在項目啓動的時候到數據庫中查找出國家和城市的數據,進行緩存,之後將數據去除。

6.1  項目啓動時緩存數據

 

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

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

import org.apache.log4j.Logger;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.ApplicationListener;

import org.springframework.context.event.ContextRefreshedEvent;

import org.springframework.stereotype.Service;

 

import com.test.model.City;

import com.test.model.Country;

import com.zcr.test.User;

 

/*

 * 監聽器,用於項目啓動的時候初始化信息

 */

@Service

public class StartAddCacheListener implements ApplicationListener<ContextRefreshedEvent>

{

 //日誌

 private final Logger log= Logger.getLogger(StartAddCacheListener.class);

  

 @Autowired

 private RedisCacheUtil<Object> redisCache;

  

 @Autowired

 private BrandStoreService brandStoreService;

  

 @Override

 public void onApplicationEvent(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<City> cityList = brandStoreService.selectAllCityMessage();

   List<Country> countryList = brandStoreService.selectAllCountryMessage();

    

   Map<Integer,City> cityMap = new HashMap<Integer,City>();

    

   Map<Integer,Country> countryMap = new HashMap<Integer, Country>();

    

   int cityListSize = cityList.size();

   int countryListSize = countryList.size();

    

   for(int i = 0 ; i < cityListSize ; i ++ )

   {

    cityMap.put(cityList.get(i).getCity_id(), cityList.get(i));

   }

    

   for(int i = 0 ; i < countryListSize ; i ++ )

   {

    countryMap.put(countryList.get(i).getCountry_id(), countryList.get(i));

   }

    

   redisCache.setCacheIntegerMap("cityMap", cityMap);

   redisCache.setCacheIntegerMap("countryMap", countryMap);

  }

 }

  

}

6.2  獲取緩存數據

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

@Autowired

private RedisCacheUtil<User> redisCache;

 

@RequestMapping("testGetCache")

public void testGetCache()

{

 /*Map<String,Country> countryMap = redisCacheUtil1.getCacheMap("country");

 Map<String,City> cityMap = redisCacheUtil.getCacheMap("city");*/

 Map<Integer,Country> countryMap = redisCacheUtil1.getCacheIntegerMap("countryMap");

 Map<Integer,City> cityMap = redisCacheUtil.getCacheIntegerMap("cityMap");

  

 for(int key : countryMap.keySet())

 {

  System.out.println("key = " + key + ",value=" + countryMap.get(key));

 }

  

 System.out.println("------------city");

 for(int key : cityMap.keySet())

 {

  System.out.println("key = " + key + ",value=" + cityMap.get(key));

 }

}

由於Spring在配置文件中配置的bean默認是單例的,所以只需要通過Autowired注入,即可得到原先的緩存類。

以上就是spring+redis實現數據緩存的方法,希望對大家的學習有所幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章