博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring + redis 实现数据的缓存
阅读量:2117 次
发布时间:2019-04-30

本文共 11849 字,大约阅读时间需要 39 分钟。

1、实现目标

通过redis缓存数据。(目的不是加快查询的速度,而是减少数据库的负担)

2、所需jar包

注意:jdies和commons-pool两个jar的版本是有对应关系的,注意引入jar包是要配对使用,否则将会报错。因为commons-pooljar的目录根据版本的变化,目录结构会变。前面的版本是org.apache.pool,而后面的版本是org.apache.pool2…

style=”background-color: #0098dd; 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

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
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注入,即可得到原先的缓存类。

原文出处: 

from: http://www.importnew.com/22868.html

转载地址:http://sfref.baihongyu.com/

你可能感兴趣的文章
Joda Time API -2
查看>>
Spring使用Cache、整合Ehcache
查看>>
Chrome调试工具奇淫技
查看>>
30分钟快速掌握Bootstrap
查看>>
如何针对业务做DB优化
查看>>
程序猿都该知道的MySQL秘籍
查看>>
Eclipse全面提速小技巧
查看>>
前端程序员必知的30个Chrome扩展
查看>>
memcached分布式实现原理
查看>>
怎么成为架构师
查看>>
40个重要的HTML 5面试问题及答案
查看>>
在Java中如何高效判断数组中是否包含某个元素
查看>>
设计模式总结
查看>>
什么时候可以使用Ehcache缓存
查看>>
Java核心知识点-JVM结构和工作方式
查看>>
Java编程中“为了性能”一些尽量做到的地方
查看>>
Java并发编程:线程池的使用
查看>>
redis单机及其集群的搭建
查看>>
Java多线程学习
查看>>
检查Linux服务器性能
查看>>