当前位置:   article > 正文

Java中RedisUtils工具类的使用_redisutil工具类

redisutil工具类

前言

本文将提供一个redis的工具类,可以用在Spring boot以及Spring Cloud项目中,本工具类主要整合了将Redis作为NoSql DB使用时的常用方法,以StringRedisTemplate实例为基础,封装了读取、写入、批量写入多个Redis hash等方法,降低了Redis学习成本,使业务代码更加高效、简洁、优雅。

一.pom.xml引入所需依赖

本依赖主要用于使用HashMultimap,该hashmap是java中的HashMap增强版,可以允许键值对中的key重复,此种特性可以用于Redis批量更新hash。后文详细讲述。

  1. <dependency>
  2. <groupId>com.google.guava</groupId>
  3. <artifactId>guava</artifactId>
  4. <version>31.1-jre</version>
  5. </dependency>

二.RedisUtils工具类

直接上源码,新建个Class,将其命名为RedisUtils ,后将首行包名修改下即可使用。

  1. package com.jtyjy.smart.redis.rock.service.utils;
  2. import com.google.common.collect.HashMultimap;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.dao.DataAccessException;
  5. import org.springframework.data.redis.connection.RedisConnection;
  6. import org.springframework.data.redis.core.*;
  7. import org.springframework.stereotype.Component;
  8. import java.util.*;
  9. import java.util.concurrent.TimeUnit;
  10. /**
  11. * @author Administrator
  12. */
  13. @Component
  14. public class RedisUtils {
  15. @Autowired
  16. private StringRedisTemplate redisTemplate;
  17. public RedisUtils(StringRedisTemplate redisTemplate) {
  18. this.redisTemplate = redisTemplate;
  19. }
  20. /**
  21. * 写入缓存
  22. *
  23. * @param key redis键
  24. * @param value redis值
  25. * @return 是否成功
  26. */
  27. public boolean set(final String key, String value) {
  28. boolean result = false;
  29. try {
  30. ValueOperations<String, String> operations = redisTemplate.opsForValue();
  31. operations.set(key, value);
  32. result = true;
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. }
  36. return result;
  37. }
  38. /**
  39. * 写入缓存设置时效时间
  40. *
  41. * @param key redis键
  42. * @param value redis值
  43. * @return 是否成功
  44. */
  45. public boolean set(final String key, String value, Long expireTime) {
  46. boolean result = false;
  47. try {
  48. ValueOperations<String, String> operations = redisTemplate.opsForValue();
  49. operations.set(key, value);
  50. redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
  51. result = true;
  52. } catch (Exception e) {
  53. e.printStackTrace();
  54. }
  55. return result;
  56. }
  57. /**
  58. * 批量删除对应的键值对
  59. *
  60. * @param keys Redis键名数组
  61. */
  62. public void removeByKeys(final String... keys) {
  63. for (String key : keys) {
  64. remove(key);
  65. }
  66. }
  67. /**
  68. * 批量删除Redis key
  69. *
  70. * @param pattern 键名包含字符串(如:myKey*)
  71. */
  72. public void removePattern(final String pattern) {
  73. Set<String> keys = redisTemplate.keys(pattern);
  74. if (keys != null && keys.size() > 0) {
  75. redisTemplate.delete(keys);
  76. }
  77. }
  78. /**
  79. * 删除key,也删除对应的value
  80. *
  81. * @param key Redis键名
  82. */
  83. public void remove(final String key) {
  84. if (exists(key)) {
  85. redisTemplate.delete(key);
  86. }
  87. }
  88. /**
  89. * 判断缓存中是否有对应的value
  90. *
  91. * @param key Redis键名
  92. * @return 是否存在
  93. */
  94. public Boolean exists(final String key) {
  95. return redisTemplate.hasKey(key);
  96. }
  97. /**
  98. * 读取缓存
  99. *
  100. * @param key Redis键名
  101. * @return 是否存在
  102. */
  103. public String get(final String key) {
  104. String result = null;
  105. ValueOperations<String, String> operations = redisTemplate.opsForValue();
  106. result = operations.get(key);
  107. return result;
  108. }
  109. /**
  110. * 哈希 添加
  111. *
  112. * @param key Redis键
  113. * @param hashKey 哈希键
  114. * @param value 哈希值
  115. */
  116. public void hmSet(String key, String hashKey, String value) {
  117. HashOperations<String, String, String> hash = redisTemplate.opsForHash();
  118. hash.put(key, hashKey, value);
  119. }
  120. /**
  121. * 哈希获取数据
  122. *
  123. * @param key Redis键
  124. * @param hashKey 哈希键
  125. * @return 哈希值
  126. */
  127. public String hmGet(String key, String hashKey) {
  128. HashOperations<String, String, String> hash = redisTemplate.opsForHash();
  129. return hash.get(key, hashKey);
  130. }
  131. /**
  132. * 判断hash是否存在键
  133. *
  134. * @param key Redis键
  135. * @param hashKey 哈希键
  136. * @return 是否存在
  137. */
  138. public boolean hmHasKey(String key, String hashKey) {
  139. HashOperations<String, String, String> hash = redisTemplate.opsForHash();
  140. return hash.hasKey(key, hashKey);
  141. }
  142. /**
  143. * 删除hash中一条或多条数据
  144. *
  145. * @param key Redis键
  146. * @param hashKeys 哈希键名数组
  147. * @return 删除数量
  148. */
  149. public long hmRemove(String key, String... hashKeys) {
  150. HashOperations<String, String, String> hash = redisTemplate.opsForHash();
  151. return hash.delete(key, hashKeys);
  152. }
  153. /**
  154. * 获取所有哈希键值对
  155. *
  156. * @param key Redis键名
  157. * @return 哈希Map
  158. */
  159. public Map<String, String> hashMapGet(String key) {
  160. HashOperations<String, String, String> hash = redisTemplate.opsForHash();
  161. return hash.entries(key);
  162. }
  163. /**
  164. * 保存Map到哈希
  165. *
  166. * @param key Redis键名
  167. * @param map 哈希Map
  168. */
  169. public void hashMapSet(String key, Map<String, String> map) {
  170. HashOperations<String, String, String> hash = redisTemplate.opsForHash();
  171. hash.putAll(key, map);
  172. }
  173. /**
  174. * 列表-追加值
  175. *
  176. * @param key Redis键名
  177. * @param value 列表值
  178. */
  179. public void lPush(String key, String value) {
  180. ListOperations<String, String> list = redisTemplate.opsForList();
  181. list.rightPush(key, value);
  182. }
  183. /**
  184. * 列表-获取指定范围数据
  185. *
  186. * @param key Redis键名
  187. * @param start 开始行号
  188. * @param end 结束行号
  189. * @return 列表
  190. */
  191. public List<String> lRange(String key, long start, long end) {
  192. ListOperations<String, String> list = redisTemplate.opsForList();
  193. return list.range(key, start, end);
  194. }
  195. /**
  196. * 集合添加
  197. *
  198. * @param key Redis键名
  199. * @param value 值
  200. */
  201. public void add(String key, String value) {
  202. SetOperations<String, String> set = redisTemplate.opsForSet();
  203. set.add(key, value);
  204. }
  205. /**
  206. * 集合获取
  207. *
  208. * @param key Redis键名
  209. * @return 集合
  210. */
  211. public Set<String> setMembers(String key) {
  212. SetOperations<String, String> set = redisTemplate.opsForSet();
  213. return set.members(key);
  214. }
  215. /**
  216. * 有序集合添加
  217. *
  218. * @param key Redis键名
  219. * @param value 值
  220. * @param score 排序号
  221. */
  222. public void zAdd(String key, String value, double score) {
  223. ZSetOperations<String, String> zSet = redisTemplate.opsForZSet();
  224. zSet.add(key, value, score);
  225. }
  226. /**
  227. * 有序集合-获取指定范围
  228. *
  229. * @param key Redis键
  230. * @param startScore 开始序号
  231. * @param endScore 结束序号
  232. * @return 集合
  233. */
  234. public Set<String> rangeByScore(String key, double startScore, double endScore) {
  235. ZSetOperations<String, String> zset = redisTemplate.opsForZSet();
  236. return zset.rangeByScore(key, startScore, endScore);
  237. }
  238. /**
  239. * 模糊查询Redis键名
  240. *
  241. * @param pattern 键名包含字符串(如:myKey*)
  242. * @return 集合
  243. */
  244. public Set<String> keys(String pattern) {
  245. return redisTemplate.keys(pattern);
  246. }
  247. /**
  248. * 获取多个hashMap
  249. *
  250. * @param keySet
  251. * @return List<Map < String, String>> hashMap列表
  252. */
  253. public List hashMapList(Collection<String> keySet) {
  254. return redisTemplate.executePipelined(new SessionCallback<String>() {
  255. @Override
  256. public <K, V> String execute(RedisOperations<K, V> operations) throws DataAccessException {
  257. HashOperations hashOperations = operations.opsForHash();
  258. for (String key : keySet) {
  259. hashOperations.entries(key);
  260. }
  261. return null;
  262. }
  263. });
  264. }
  265. /**
  266. * 保存多个哈希表(HashMap)(Redis键名可重复)
  267. *
  268. * @param batchMap Map<Redis键名,Map<键,值>>
  269. */
  270. public void batchHashMapSet(HashMultimap<String, Map<String, String>> batchMap) {
  271. // 设置5秒超时时间
  272. redisTemplate.expire("max", 25, TimeUnit.SECONDS);
  273. redisTemplate.executePipelined(new RedisCallback<List<Map<String, String>>>() {
  274. @Override
  275. public List<Map<String, String>> doInRedis(RedisConnection connection) throws DataAccessException {
  276. Iterator<Map.Entry<String, Map<String, String>>> iterator = batchMap.entries().iterator();
  277. while (iterator.hasNext()) {
  278. Map.Entry<String, Map<String, String>> hash = iterator.next();
  279. // 哈希名,即表名
  280. byte[] hashName = redisTemplate.getStringSerializer().serialize(hash.getKey());
  281. Map<String, String> hashValues = hash.getValue();
  282. Iterator<Map.Entry<String, String>> it = hashValues.entrySet().iterator();
  283. // 将元素序列化后缓存,即表的多条哈希记录
  284. Map<byte[], byte[]> hashes = new HashMap<byte[], byte[]>();
  285. while (it.hasNext()) {
  286. // hash中一条key-value记录
  287. Map.Entry<String, String> entry = it.next();
  288. byte[] key = redisTemplate.getStringSerializer().serialize(entry.getKey());
  289. byte[] value = redisTemplate.getStringSerializer().serialize(entry.getValue());
  290. hashes.put(key, value);
  291. }
  292. // 批量保存
  293. connection.hMSet(hashName, hashes);
  294. }
  295. return null;
  296. }
  297. });
  298. }
  299. /**
  300. * 保存多个哈希表(HashMap)(Redis键名不可以重复)
  301. *
  302. * @param dataMap Map<Redis键名,Map<哈希键,哈希值>>
  303. */
  304. public void batchHashMapSet(Map<String, Map<String, String>> dataMap) {
  305. // 设置5秒超时时间
  306. redisTemplate.expire("max", 25, TimeUnit.SECONDS);
  307. redisTemplate.executePipelined(new RedisCallback<List<Map<String, String>>>() {
  308. @Override
  309. public List<Map<String, String>> doInRedis(RedisConnection connection) throws DataAccessException {
  310. Iterator<Map.Entry<String, Map<String, String>>> iterator = dataMap.entrySet().iterator();
  311. while (iterator.hasNext()) {
  312. Map.Entry<String, Map<String, String>> hash = iterator.next();
  313. // 哈希名,即表名
  314. byte[] hashName = redisTemplate.getStringSerializer().serialize(hash.getKey());
  315. Map<String, String> hashValues = hash.getValue();
  316. Iterator<Map.Entry<String, String>> it = hashValues.entrySet().iterator();
  317. // 将元素序列化后缓存,即表的多条哈希记录
  318. Map<byte[], byte[]> hashes = new HashMap<byte[], byte[]>();
  319. while (it.hasNext()) {
  320. // hash中一条key-value记录
  321. Map.Entry<String, String> entry = it.next();
  322. byte[] key = redisTemplate.getStringSerializer().serialize(entry.getKey());
  323. byte[] value = redisTemplate.getStringSerializer().serialize(entry.getValue());
  324. hashes.put(key, value);
  325. }
  326. // 批量保存
  327. connection.hMSet(hashName, hashes);
  328. }
  329. return null;
  330. }
  331. });
  332. }
  333. /**
  334. * 保存多个哈希表(HashMap)列表(哈希map的Redis键名不能重复)
  335. *
  336. * @param list Map<Redis键名,Map<哈希键,哈希值>>
  337. * @see RedisUtils*.batchHashMapSet()*
  338. */
  339. public void batchHashMapListSet(List<Map<String, Map<String, String>>> list) {
  340. // 设置5秒超时时间
  341. redisTemplate.expire("max", 25, TimeUnit.SECONDS);
  342. redisTemplate.executePipelined(new RedisCallback<List<Map<String, String>>>() {
  343. @Override
  344. public List<Map<String, String>> doInRedis(RedisConnection connection) throws DataAccessException {
  345. for (Map<String, Map<String, String>> dataMap : list) {
  346. Iterator<Map.Entry<String, Map<String, String>>> iterator = dataMap.entrySet().iterator();
  347. while (iterator.hasNext()) {
  348. Map.Entry<String, Map<String, String>> hash = iterator.next();
  349. // 哈希名,即表名
  350. byte[] hashName = redisTemplate.getStringSerializer().serialize(hash.getKey());
  351. Map<String, String> hashValues = hash.getValue();
  352. Iterator<Map.Entry<String, String>> it = hashValues.entrySet().iterator();
  353. // 将元素序列化后缓存,即表的多条哈希记录
  354. Map<byte[], byte[]> hashes = new HashMap<byte[], byte[]>();
  355. while (it.hasNext()) {
  356. // hash中一条key-value记录
  357. Map.Entry<String, String> entry = it.next();
  358. byte[] key = redisTemplate.getStringSerializer().serialize(entry.getKey());
  359. byte[] value = redisTemplate.getStringSerializer().serialize(entry.getValue());
  360. hashes.put(key, value);
  361. }
  362. // 批量保存
  363. connection.hMSet(hashName, hashes);
  364. }
  365. }
  366. return null;
  367. }
  368. });
  369. }
  370. }

三.如何使用工具类

  1. @Service
  2. public class ProductServiceImpl implements ProductService {
  3. @Autowired
  4. private ProductRepository productRepository;
  5. @Autowired
  6. private RedisUtils redisUtils;
  7. private final String EMPTY_CACHE = "empty";
  8. private final Long PRODUCT_CACHE_TIMEOUT = 360L;
  9. @Override
  10. public Product getRedisProduct(Integer productId){
  11. Product product;
  12. String productCacheKey = RedisKeyPrefixConstant.PRODUCT_CACHE + productId;
  13. String productStr = redisUtils.get(productCacheKey);
  14. if(!StringUtils.isEmpty(productStr)){
  15. if(EMPTY_CACHE.equals(productStr)){
  16. return null;
  17. }
  18. product = JSON.parseObject(productStr,Product.class);
  19. return product;
  20. }
  21. product = productRepository.findById(productId).orElse(null);
  22. if(product!=null){
  23. redisUtils.set(productCacheKey,JSON.toJSONString(product),getProductCacheTimeout());
  24. return product;
  25. }else {
  26. redisUtils.set(productCacheKey,EMPTY_CACHE,getEmptyCacheTimeout());
  27. return null;
  28. }
  29. }
  30. }

四.工具类中批量更新Redis Hash详解

工具类中batchHashMapSet()重载的方法有两个,特别的是,其中一个方法是支持key值重复的,也就说可以同时更新或写入Redis 键名相同的两个hash,后写入的hash会把先写入的数据覆盖,适合一些实时往Redis同步数据的业务场景。

使用方法:

  1. HashMultimap<String, Map<String, String>> batchMap = HashMultimap.create();
  2. redisUtils.batchHashMapSet(batchMap);

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/240541
推荐阅读
相关标签
  

闽ICP备14008679号