一、Redis介绍
什么是Redis?
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
它有什么特点?
(1)Redis数据库完全在内存中,使用磁盘仅用于持久性。(2)相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。(3)Redis可以将数据复制到任意数量的从服务器。
Redis 优势? (1)异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录。 (2)支持丰富的数据类型:Redis支持最大多数开发人员已经知道像列表,集合,有序集合,散列数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以处理通过它的数据类型更好。(3)操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。(4)多功能实用工具:Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如Web应用程序会话,网页命中计数等。
Redis 缺点?
(1)单线程
(2)耗内存
二、使用实例
spring把专门的数据操作独立封装在spring-data系列中,spring-data-redis自然是针对Redis的独立封装了。
主要是将jedis、jredis、rjc以及srp等Redis Client进行了封装,同时支持事务。
1、引入相关jar包(连接池不做考虑)
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
2、配置bean
新增application-redis.xml加入如下配置
1.
2.
3.
4.
5.
6. >
7.
8.
9.
10.
11.
12.
13.
14. >
15.
16.
17.
18.
19.
20.
21.
22.
23. >
其中配置文件redis一些配置数据redis.properties如下:
1. #redis中心
2. redis.host=1127.0.0.1
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. targetNames=xxxRecordManager,xxxSetRecordManager,xxxStatisticsIdentificationManager
12. # 不需要缓存的方法
13. methodNames=
14.
15. #设置缓存失效时间
16. com.service.impl.xxxRecordManager= 60
17. com.service.impl.xxxSetRecordManager= 60
18. defaultCacheExpireTime=3600
19.
20. fep.local.cache.capacity =10000
3、一些工具类
(1)RedisUtil
上面的bean中,RedisUtil是用来缓存和去除数据的实例
1. package com.itshow.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. */
15. @Component
16. public final class RedisUtil {
17. private Logger logger = Logger.getLogger(RedisUtil.class);
18.
19. @Autowired
20. private RedisTemplate
21.
22. /**
23. * 批量删除对应的value
24. *
25. * @param keys
26. */
27. public void remove(final String... keys) {
28. for (String key : keys) {
29. remove(key);
30. }
31. }
32.
33. /**
34. * 批量删除key
35. *
36. * @param pattern
37. */
38. public void removePattern(final String pattern) {
39. Set
40. if (keys.size() > 0)
41. redisTemplate.delete(keys);
42. }
43.
44. /**
45. * 删除对应的value
46. *
47. * @param key
48. */
49. public void remove(final String key) {
50. if (exists(key)) {
51. redisTemplate.delete(key);
52. }
53. }
54.
55. /**
56. * 判断缓存中是否有对应的value
57. *
58. * @param key
59. * @return
60. */
61. public boolean exists(final String key) {
62. return redisTemplate.hasKey(key);
63. }
64.
65. /**
66. * 读取缓存
67. *
68. * @param key
69. * @return
70. */
71. public Object get(final String key) {
72. Object result = null;
73. ValueOperations
74. .opsForValue();
75. result = operations.get(key);
76. return result;
77. }
78.
79. /**
80. * 写入缓存
81. *
82. * @param key
83. * @param value
84. * @return
85. */
86. public boolean set(final String key, Object value) {
87. boolean result = false;
88. try {
89. ValueOperations
90. .opsForValue();
91. operations.set(key, value);
92. result = true;
93. } catch (Exception e) {
94. e.printStackTrace();
95. }
96. return result;
97. }
98.
99. /**
100. * 写入缓存
101. *
102. * @param key
103. * @param value
104. * @return
105. */
106. public boolean set(final String key, Object value, Long expireTime) {
107. boolean result = false;
108. try {
109. ValueOperations
110. .opsForValue();
111. operations.set(key, value);
112. redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
113. result = true;
114. } catch (Exception e) {
115. e.printStackTrace();
116. }
117. return result;
118. }
119.
120. public void setRedisTemplate(
121. RedisTemplate
122. this.redisTemplate = redisTemplate;
123. }
124. }
(2)MethodCacheInterceptor
切面MethodCacheInterceptor,这是用来给不同的方法来加入判断如果缓存存在数据,从缓存取数据。否则第一次从数据库取,并将结果保存到缓存 中去。
1. package com.itshow.common;
2.
3. import java.io.File;
4. import java.io.FileInputStream;
5. import java.io.InputStream;
6. import java.util.List;
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. @Interceptor
15. public class MethodCacheInterceptor implements MethodInterceptor {
16. private Logger logger = Logger.getLogger(MethodCacheInterceptor.class);
17. @Autowired
18. private RedisUtil redisUtil;
19. private List
20. private List
21. private Long defaultCacheExpireTime; // 缓存默认的过期时间
22. private Long xxxRecordManagerTime; //
23. private Long xxxSetRecordManagerTime; //
24.
25. /**
26. * 初始化读取不需要加入缓存的类名和方法名称
27. */
28. public MethodCacheInterceptor() {
29. //初始化参数.....
30. }
31.
32. @Override
33. public Object invoke(MethodInvocation invocation) throws Throwable {
34. Object value = null;
35.
36. String targetName = invocation.getThis().getClass().getName();
37. String methodName = invocation.getMethod().getName();
38. // 不需要缓存的内容
39. //if (!isAddCache(StringUtil.subStrForLastDot(targetName), methodName)) {
40. if (!isAddCache(targetName, methodName)) {
41. // 执行方法返回结果
42. return invocation.proceed();
43. }
44. Object[] arguments = invocation.getArguments();
45. String key = getCacheKey(targetName, methodName, arguments);
46. System.out.println(key);
47.
48. try {
49. // 判断是否有缓存
50. if (redisUtil.exists(key)) {
51. return redisUtil.get(key);
52. }
53. // 写入缓存
54. value = invocation.proceed();
55. if (value != null) {
56. final String tkey = key;
57. final Object tvalue = value;
58. new Thread(new Runnable() {
59. @Override
60. public void run() {
61. if (tkey.startsWith("com.service.impl.xxxRecordManager")) {
62. redisUtil.set(tkey, tvalue, xxxRecordManagerTime);
63. } else if (tkey.startsWith("com.service.impl.xxxSetRecordManager")) {
64. redisUtil.set(tkey, tvalue, xxxSetRecordManagerTime);
65. } else {
66. redisUtil.set(tkey, tvalue, defaultCacheExpireTime);
67. }
68. }
69. }).start();
70. }
71. } catch (Exception e) {
72. e.printStackTrace();
73. if (value == null) {
74. return invocation.proceed();
75. }
76. }
77. return value;
78. }
79.
80. /**
81. * 是否加入缓存
82. *
83. * @return
84. */
85. private boolean isAddCache(String targetName, String methodName) {
86. boolean flag = true;
87. if (targetNamesList.contains(targetName)
88. || methodNamesList.contains(methodName)) {
89. flag = false;
90. }
91. return flag;
92. }
93.
94. /**
95. * 创建缓存key
96. *
97. * @param targetName
98. * @param methodName
99. * @param arguments
100. */
101. private String getCacheKey(String targetName, String methodName,
102. Object[] arguments) {
103. StringBuffer sbu = new StringBuffer();
104. sbu.append(targetName).append("_").append(methodName);
105. if ((arguments != null) && (arguments.length != 0)) {
106. for (int i = 0; i < arguments.length; i++) {
107. sbu.append("_").append(arguments[i]);
108. }
109. }
110. return sbu.toString();
111. }
112.
113. public void setRedisUtil(RedisUtil redisUtil) {
114. this.redisUtil = redisUtil;
115. }
116. }
¥29.8
¥9.9
¥59.8