RedisUtil.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. package com.genersoft.iot.vmp.utils.redis;
  2. import java.util.*;
  3. import java.util.concurrent.TimeUnit;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.data.redis.core.*;
  6. import org.springframework.stereotype.Component;
  7. import org.springframework.util.CollectionUtils;
  8. /**
  9. * @Description:Redis工具类
  10. * @author: swwheihei
  11. * @date: 2020年5月6日 下午8:27:29
  12. */
  13. @Component
  14. @SuppressWarnings(value = {"rawtypes", "unchecked"})
  15. public class RedisUtil {
  16. @Autowired
  17. private RedisTemplate redisTemplate;
  18. /**
  19. * 指定缓存失效时间
  20. * @param key 键
  21. * @param time 时间(秒)
  22. * @return true / false
  23. */
  24. public boolean expire(String key, long time) {
  25. try {
  26. if (time > 0) {
  27. redisTemplate.expire(key, time, TimeUnit.SECONDS);
  28. }
  29. return true;
  30. } catch (Exception e) {
  31. e.printStackTrace();
  32. return false;
  33. }
  34. }
  35. /**
  36. * 根据 key 获取过期时间
  37. * @param key 键
  38. * @return
  39. */
  40. public long getExpire(String key) {
  41. return redisTemplate.getExpire(key, TimeUnit.SECONDS);
  42. }
  43. /**
  44. * 判断 key 是否存在
  45. * @param key 键
  46. * @return true / false
  47. */
  48. public boolean hasKey(String key) {
  49. try {
  50. return redisTemplate.hasKey(key);
  51. } catch (Exception e) {
  52. e.printStackTrace();
  53. return false;
  54. }
  55. }
  56. /**
  57. * 删除缓存
  58. * @SuppressWarnings("unchecked") 忽略类型转换警告
  59. * @param key 键(一个或者多个)
  60. */
  61. public boolean del(String... key) {
  62. try {
  63. if (key != null && key.length > 0) {
  64. if (key.length == 1) {
  65. redisTemplate.delete(key[0]);
  66. } else {
  67. // 传入一个 Collection<String> 集合
  68. redisTemplate.delete(CollectionUtils.arrayToList(key));
  69. }
  70. }
  71. return true;
  72. } catch (Exception e) {
  73. e.printStackTrace();
  74. return false;
  75. }
  76. }
  77. // ============================== String ==============================
  78. /**
  79. * 普通缓存获取
  80. * @param key 键
  81. * @return 值
  82. */
  83. public Object get(String key) {
  84. return key == null ? null : redisTemplate.opsForValue().get(key);
  85. }
  86. /**
  87. * 普通缓存放入
  88. * @param key 键
  89. * @param value 值
  90. * @return true / false
  91. */
  92. public boolean set(String key, Object value) {
  93. try {
  94. redisTemplate.opsForValue().set(key, value);
  95. return true;
  96. } catch (Exception e) {
  97. e.printStackTrace();
  98. return false;
  99. }
  100. }
  101. /**
  102. * 普通缓存放入并设置时间
  103. * @param key 键
  104. * @param value 值
  105. * @param time 时间(秒),如果 time < 0 则设置无限时间
  106. * @return true / false
  107. */
  108. public boolean set(String key, Object value, long time) {
  109. try {
  110. if (time > 0) {
  111. redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
  112. } else {
  113. set(key, value);
  114. }
  115. return true;
  116. } catch (Exception e) {
  117. e.printStackTrace();
  118. return false;
  119. }
  120. }
  121. /**
  122. * 递增
  123. * @param key 键
  124. * @param delta 递增大小
  125. * @return
  126. */
  127. public long incr(String key, long delta) {
  128. if (delta < 0) {
  129. throw new RuntimeException("递增因子必须大于 0");
  130. }
  131. return redisTemplate.opsForValue().increment(key, delta);
  132. }
  133. /**
  134. * 递减
  135. * @param key 键
  136. * @param delta 递减大小
  137. * @return
  138. */
  139. public long decr(String key, long delta) {
  140. if (delta < 0) {
  141. throw new RuntimeException("递减因子必须大于 0");
  142. }
  143. return redisTemplate.opsForValue().increment(key, delta);
  144. }
  145. // ============================== Map ==============================
  146. /**
  147. * HashGet
  148. * @param key 键(no null)
  149. * @param item 项(no null)
  150. * @return 值
  151. */
  152. public Object hget(String key, String item) {
  153. return redisTemplate.opsForHash().get(key, item);
  154. }
  155. /**
  156. * 获取 key 对应的 map
  157. * @param key 键(no null)
  158. * @return 对应的多个键值
  159. */
  160. public Map<Object, Object> hmget(String key) {
  161. return redisTemplate.opsForHash().entries(key);
  162. }
  163. /**
  164. * HashSet
  165. * @param key 键
  166. * @param map 值
  167. * @return true / false
  168. */
  169. public boolean hmset(String key, Map<Object, Object> map) {
  170. try {
  171. redisTemplate.opsForHash().putAll(key, map);
  172. return true;
  173. } catch (Exception e) {
  174. e.printStackTrace();
  175. return false;
  176. }
  177. }
  178. /**
  179. * HashSet 并设置时间
  180. * @param key 键
  181. * @param map 值
  182. * @param time 时间
  183. * @return true / false
  184. */
  185. public boolean hmset(String key, Map<Object, Object> map, long time) {
  186. try {
  187. redisTemplate.opsForHash().putAll(key, map);
  188. if (time > 0) {
  189. expire(key, time);
  190. }
  191. return true;
  192. } catch (Exception e) {
  193. e.printStackTrace();
  194. return false;
  195. }
  196. }
  197. /**
  198. * 向一张 Hash表 中放入数据,如不存在则创建
  199. * @param key 键
  200. * @param item 项
  201. * @param value 值
  202. * @return true / false
  203. */
  204. public boolean hset(String key, String item, Object value) {
  205. try {
  206. redisTemplate.opsForHash().put(key, item, value);
  207. return true;
  208. } catch (Exception e) {
  209. e.printStackTrace();
  210. return false;
  211. }
  212. }
  213. /**
  214. * 向一张 Hash表 中放入数据,并设置时间,如不存在则创建
  215. * @param key 键
  216. * @param item 项
  217. * @param value 值
  218. * @param time 时间(如果原来的 Hash表 设置了时间,这里会覆盖)
  219. * @return true / false
  220. */
  221. public boolean hset(String key, String item, Object value, long time) {
  222. try {
  223. redisTemplate.opsForHash().put(key, item, value);
  224. if (time > 0) {
  225. expire(key, time);
  226. }
  227. return true;
  228. } catch (Exception e) {
  229. e.printStackTrace();
  230. return false;
  231. }
  232. }
  233. /**
  234. * 删除 Hash表 中的值
  235. * @param key 键
  236. * @param item 项(可以多个,no null)
  237. */
  238. public void hdel(String key, Object... item) {
  239. redisTemplate.opsForHash().delete(key, item);
  240. }
  241. /**
  242. * 判断 Hash表 中是否有该键的值
  243. * @param key 键(no null)
  244. * @param item 值(no null)
  245. * @return true / false
  246. */
  247. public boolean hHasKey(String key, String item) {
  248. return redisTemplate.opsForHash().hasKey(key, item);
  249. }
  250. /**
  251. * Hash递增,如果不存在则创建一个,并把新增的值返回
  252. * @param key 键
  253. * @param item 项
  254. * @param by 递增大小 > 0
  255. * @return
  256. */
  257. public Double hincr(String key, String item, Double by) {
  258. return redisTemplate.opsForHash().increment(key, item, by);
  259. }
  260. /**
  261. * Hash递减
  262. * @param key 键
  263. * @param item 项
  264. * @param by 递减大小
  265. * @return
  266. */
  267. public Double hdecr(String key, String item, Double by) {
  268. return redisTemplate.opsForHash().increment(key, item, -by);
  269. }
  270. // ============================== Set ==============================
  271. /**
  272. * 根据 key 获取 set 中的所有值
  273. * @param key 键
  274. * @return 值
  275. */
  276. public Set<Object> sGet(String key) {
  277. try {
  278. return redisTemplate.opsForSet().members(key);
  279. } catch (Exception e) {
  280. e.printStackTrace();
  281. return null;
  282. }
  283. }
  284. /**
  285. * 从键为 key 的 set 中,根据 value 查询是否存在
  286. * @param key 键
  287. * @param value 值
  288. * @return true / false
  289. */
  290. public boolean sHasKey(String key, Object value) {
  291. try {
  292. return redisTemplate.opsForSet().isMember(key, value);
  293. } catch (Exception e) {
  294. e.printStackTrace();
  295. return false;
  296. }
  297. }
  298. /**
  299. * 将数据放入 set缓存
  300. * @param key 键值
  301. * @param values 值(可以多个)
  302. * @return 成功个数
  303. */
  304. public long sSet(String key, Object... values) {
  305. try {
  306. return redisTemplate.opsForSet().add(key, values);
  307. } catch (Exception e) {
  308. e.printStackTrace();
  309. return 0;
  310. }
  311. }
  312. /**
  313. * 将数据放入 set缓存,并设置时间
  314. * @param key 键
  315. * @param time 时间
  316. * @param values 值(可以多个)
  317. * @return 成功放入个数
  318. */
  319. public long sSet(String key, long time, Object... values) {
  320. try {
  321. long count = redisTemplate.opsForSet().add(key, values);
  322. if (time > 0) {
  323. expire(key, time);
  324. }
  325. return count;
  326. } catch (Exception e) {
  327. e.printStackTrace();
  328. return 0;
  329. }
  330. }
  331. /**
  332. * 获取 set缓存的长度
  333. * @param key 键
  334. * @return 长度
  335. */
  336. public long sGetSetSize(String key) {
  337. try {
  338. return redisTemplate.opsForSet().size(key);
  339. } catch (Exception e) {
  340. e.printStackTrace();
  341. return 0;
  342. }
  343. }
  344. /**
  345. * 移除 set缓存中,值为 value 的
  346. * @param key 键
  347. * @param values 值
  348. * @return 成功移除个数
  349. */
  350. public long setRemove(String key, Object... values) {
  351. try {
  352. return redisTemplate.opsForSet().remove(key, values);
  353. } catch (Exception e) {
  354. e.printStackTrace();
  355. return 0;
  356. }
  357. }
  358. // ============================== ZSet ==============================
  359. /**
  360. * 添加一个元素, zset与set最大的区别就是每个元素都有一个score,因此有个排序的辅助功能; zadd
  361. *
  362. * @param key
  363. * @param value
  364. * @param score
  365. */
  366. public void zAdd(String key, String value, double score) {
  367. redisTemplate.opsForZSet().add(key, value, score);
  368. }
  369. /**
  370. * 删除元素 zrem
  371. *
  372. * @param key
  373. * @param value
  374. */
  375. public void zRemove(String key, String value) {
  376. redisTemplate.opsForZSet().remove(key, value);
  377. }
  378. /**
  379. * score的增加or减少 zincrby
  380. *
  381. * @param key
  382. * @param value
  383. * @param score
  384. */
  385. public Double zIncrScore(String key, String value, double score) {
  386. return redisTemplate.opsForZSet().incrementScore(key, value, score);
  387. }
  388. /**
  389. * 查询value对应的score zscore
  390. *
  391. * @param key
  392. * @param value
  393. * @return
  394. */
  395. public Double zScore(String key, String value) {
  396. return redisTemplate.opsForZSet().score(key, value);
  397. }
  398. /**
  399. * 判断value在zset中的排名 zrank
  400. *
  401. * @param key
  402. * @param value
  403. * @return
  404. */
  405. public Long zRank(String key, String value) {
  406. return redisTemplate.opsForZSet().rank(key, value);
  407. }
  408. /**
  409. * 返回集合的长度
  410. *
  411. * @param key
  412. * @return
  413. */
  414. public Long zSize(String key) {
  415. return redisTemplate.opsForZSet().zCard(key);
  416. }
  417. /**
  418. * 查询集合中指定顺序的值, 0 -1 表示获取全部的集合内容 zrange
  419. *
  420. * 返回有序的集合,score小的在前面
  421. *
  422. * @param key
  423. * @param start
  424. * @param end
  425. * @return
  426. */
  427. public Set<String> ZRange(String key, int start, int end) {
  428. return redisTemplate.opsForZSet().range(key, start, end);
  429. }
  430. /**
  431. * 查询集合中指定顺序的值和score,0, -1 表示获取全部的集合内容
  432. *
  433. * @param key
  434. * @param start
  435. * @param end
  436. * @return
  437. */
  438. public Set<ZSetOperations.TypedTuple<String>> zRangeWithScore(String key, int start, int end) {
  439. return redisTemplate.opsForZSet().rangeWithScores(key, start, end);
  440. }
  441. /**
  442. * 查询集合中指定顺序的值 zrevrange
  443. *
  444. * 返回有序的集合中,score大的在前面
  445. *
  446. * @param key
  447. * @param start
  448. * @param end
  449. * @return
  450. */
  451. public Set<String> zRevRange(String key, int start, int end) {
  452. return redisTemplate.opsForZSet().reverseRange(key, start, end);
  453. }
  454. /**
  455. * 根据score的值,来获取满足条件的集合 zrangebyscore
  456. *
  457. * @param key
  458. * @param min
  459. * @param max
  460. * @return
  461. */
  462. public Set<String> zSortRange(String key, int min, int max) {
  463. return redisTemplate.opsForZSet().rangeByScore(key, min, max);
  464. }
  465. // ============================== List ==============================
  466. /**
  467. * 获取 list缓存的内容
  468. * @param key 键
  469. * @param start 开始
  470. * @param end 结束(0 到 -1 代表所有值)
  471. * @return
  472. */
  473. public List<Object> lGet(String key, long start, long end) {
  474. try {
  475. return redisTemplate.opsForList().range(key, start, end);
  476. } catch (Exception e) {
  477. e.printStackTrace();
  478. return null;
  479. }
  480. }
  481. /**
  482. * 获取 list缓存的长度
  483. * @param key 键
  484. * @return 长度
  485. */
  486. public long lGetListSize(String key) {
  487. try {
  488. return redisTemplate.opsForList().size(key);
  489. } catch (Exception e) {
  490. e.printStackTrace();
  491. return 0;
  492. }
  493. }
  494. /**
  495. * 根据索引 index 获取键为 key 的 list 中的元素
  496. * @param key 键
  497. * @param index 索引
  498. * 当 index >= 0 时 {0:表头, 1:第二个元素}
  499. * 当 index < 0 时 {-1:表尾, -2:倒数第二个元素}
  500. * @return 值
  501. */
  502. public Object lGetIndex(String key, long index) {
  503. try {
  504. return redisTemplate.opsForList().index(key, index);
  505. } catch (Exception e) {
  506. e.printStackTrace();
  507. return null;
  508. }
  509. }
  510. /**
  511. * 将值 value 插入键为 key 的 list 中,如果 list 不存在则创建空 list
  512. * @param key 键
  513. * @param value 值
  514. * @return true / false
  515. */
  516. public boolean lSet(String key, Object value) {
  517. try {
  518. redisTemplate.opsForList().rightPush(key, value);
  519. return true;
  520. } catch (Exception e) {
  521. e.printStackTrace();
  522. return false;
  523. }
  524. }
  525. /**
  526. * 将值 value 插入键为 key 的 list 中,并设置时间
  527. * @param key 键
  528. * @param value 值
  529. * @param time 时间
  530. * @return true / false
  531. */
  532. public boolean lSet(String key, Object value, long time) {
  533. try {
  534. redisTemplate.opsForList().rightPush(key, value);
  535. if (time > 0) {
  536. expire(key, time);
  537. }
  538. return true;
  539. } catch (Exception e) {
  540. e.printStackTrace();
  541. return false;
  542. }
  543. }
  544. /**
  545. * 将 values 插入键为 key 的 list 中
  546. * @param key 键
  547. * @param values 值
  548. * @return true / false
  549. */
  550. public boolean lSetList(String key, List<Object> values) {
  551. try {
  552. redisTemplate.opsForList().rightPushAll(key, values);
  553. return true;
  554. } catch (Exception e) {
  555. e.printStackTrace();
  556. return false;
  557. }
  558. }
  559. /**
  560. * 将 values 插入键为 key 的 list 中,并设置时间
  561. * @param key 键
  562. * @param values 值
  563. * @param time 时间
  564. * @return true / false
  565. */
  566. public boolean lSetList(String key, List<Object> values, long time) {
  567. try {
  568. redisTemplate.opsForList().rightPushAll(key, values);
  569. if (time > 0) {
  570. expire(key, time);
  571. }
  572. return true;
  573. } catch (Exception e) {
  574. e.printStackTrace();
  575. return false;
  576. }
  577. }
  578. /**
  579. * 根据索引 index 修改键为 key 的值
  580. * @param key 键
  581. * @param index 索引
  582. * @param value 值
  583. * @return true / false
  584. */
  585. public boolean lUpdateIndex(String key, long index, Object value) {
  586. try {
  587. redisTemplate.opsForList().set(key, index, value);
  588. return true;
  589. } catch (Exception e) {
  590. e.printStackTrace();
  591. return false;
  592. }
  593. }
  594. /**
  595. * 在键为 key 的 list 中删除值为 value 的元素
  596. * @param key 键
  597. * @param count 如果 count == 0 则删除 list 中所有值为 value 的元素
  598. * 如果 count > 0 则删除 list 中最左边那个值为 value 的元素
  599. * 如果 count < 0 则删除 list 中最右边那个值为 value 的元素
  600. * @param value
  601. * @return
  602. */
  603. public long lRemove(String key, long count, Object value) {
  604. try {
  605. return redisTemplate.opsForList().remove(key, count, value);
  606. } catch (Exception e) {
  607. e.printStackTrace();
  608. return 0;
  609. }
  610. }
  611. /**
  612. * 模糊查询
  613. * @param key 键
  614. * @return true / false
  615. */
  616. public List<Object> keys(String key) {
  617. try {
  618. Set<String> set = redisTemplate.keys(key);
  619. return new ArrayList<>(set);
  620. } catch (Exception e) {
  621. e.printStackTrace();
  622. return null;
  623. }
  624. }
  625. /**
  626. * 模糊查询
  627. * @param query 查询参数
  628. * @return
  629. */
  630. // public List<Object> scan(String query) {
  631. // List<Object> result = new ArrayList<>();
  632. // try {
  633. // Cursor<Map.Entry<Object,Object>> cursor = redisTemplate.opsForHash().scan("field",
  634. // ScanOptions.scanOptions().match(query).count(1000).build());
  635. // while (cursor.hasNext()) {
  636. // Map.Entry<Object,Object> entry = cursor.next();
  637. // result.add(entry.getKey());
  638. // Object key = entry.getKey();
  639. // Object valueSet = entry.getValue();
  640. // }
  641. // //关闭cursor
  642. // cursor.close();
  643. // } catch (Exception e) {
  644. // e.printStackTrace();
  645. // }
  646. // return result;
  647. // }
  648. /**
  649. * 模糊查询
  650. * @param query 查询参数
  651. * @return
  652. */
  653. public List<Object> scan(String query) {
  654. Set<String> keys = (Set<String>) redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
  655. Set<String> keysTmp = new HashSet<>();
  656. Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(query).count(1000).build());
  657. while (cursor.hasNext()) {
  658. keysTmp.add(new String(cursor.next()));
  659. }
  660. return keysTmp;
  661. });
  662. // Set<String> keys = (Set<String>) redisTemplate.execute(new RedisCallback<Set<String>>(){
  663. //
  664. // @Override
  665. // public Set<String> doInRedis(RedisConnection connection) throws DataAccessException {
  666. // Set<String> keysTmp = new HashSet<>();
  667. // Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(query).count(1000).build());
  668. // while (cursor.hasNext()) {
  669. // keysTmp.add(new String(cursor.next()));
  670. // }
  671. // return keysTmp;
  672. // }
  673. // });
  674. return new ArrayList<>(keys);
  675. }
  676. }