08c83a10455de7c78e29d7951413822f1dac45fd.svn-base 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. package org.jeecg.common.util;
  2. import java.util.HashSet;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.Set;
  6. import java.util.concurrent.TimeUnit;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.data.redis.core.*;
  9. import org.springframework.stereotype.Component;
  10. import org.springframework.util.CollectionUtils;
  11. /**
  12. * redis 工具类
  13. * @Author Scott
  14. *
  15. */
  16. @Component
  17. public class RedisUtil {
  18. @Autowired
  19. private RedisTemplate<String, Object> redisTemplate;
  20. @Autowired
  21. private StringRedisTemplate stringRedisTemplate;
  22. /**
  23. * 指定缓存失效时间
  24. *
  25. * @param key 键
  26. * @param time 时间(秒)
  27. * @return
  28. */
  29. public boolean expire(String key, long time) {
  30. try {
  31. if (time > 0) {
  32. redisTemplate.expire(key, time, TimeUnit.SECONDS);
  33. }
  34. return true;
  35. } catch (Exception e) {
  36. e.printStackTrace();
  37. return false;
  38. }
  39. }
  40. /**
  41. * 根据key 获取过期时间
  42. *
  43. * @param key 键 不能为null
  44. * @return 时间(秒) 返回0代表为永久有效
  45. */
  46. public long getExpire(String key) {
  47. return redisTemplate.getExpire(key, TimeUnit.SECONDS);
  48. }
  49. /**
  50. * 判断key是否存在
  51. *
  52. * @param key 键
  53. * @return true 存在 false不存在
  54. */
  55. public boolean hasKey(String key) {
  56. try {
  57. return redisTemplate.hasKey(key);
  58. } catch (Exception e) {
  59. e.printStackTrace();
  60. return false;
  61. }
  62. }
  63. /**
  64. * 删除缓存
  65. *
  66. * @param key 可以传一个值 或多个
  67. */
  68. @SuppressWarnings("unchecked")
  69. public void del(String... key) {
  70. if (key != null && key.length > 0) {
  71. if (key.length == 1) {
  72. redisTemplate.delete(key[0]);
  73. } else {
  74. redisTemplate.delete(CollectionUtils.arrayToList(key));
  75. }
  76. }
  77. }
  78. // ============================String=============================
  79. /**
  80. * 普通缓存获取
  81. *
  82. * @param key 键
  83. * @return 值
  84. */
  85. public Object get(String key) {
  86. return key == null ? null : redisTemplate.opsForValue().get(key);
  87. }
  88. /**
  89. * 普通缓存放入
  90. *
  91. * @param key 键
  92. * @param value 值
  93. * @return true成功 false失败
  94. */
  95. public boolean set(String key, Object value) {
  96. try {
  97. redisTemplate.opsForValue().set(key, value);
  98. return true;
  99. } catch (Exception e) {
  100. e.printStackTrace();
  101. return false;
  102. }
  103. }
  104. /**
  105. * 普通缓存放入并设置时间
  106. *
  107. * @param key 键
  108. * @param value 值
  109. * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
  110. * @return true成功 false 失败
  111. */
  112. public boolean set(String key, Object value, long time) {
  113. try {
  114. if (time > 0) {
  115. redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
  116. } else {
  117. set(key, value);
  118. }
  119. return true;
  120. } catch (Exception e) {
  121. e.printStackTrace();
  122. return false;
  123. }
  124. }
  125. /**
  126. * 递增
  127. *
  128. * @param key 键
  129. * @param by 要增加几(大于0)
  130. * @return
  131. */
  132. public long incr(String key, long delta) {
  133. if (delta < 0) {
  134. throw new RuntimeException("递增因子必须大于0");
  135. }
  136. return redisTemplate.opsForValue().increment(key, delta);
  137. }
  138. /**
  139. * 递减
  140. *
  141. * @param key 键
  142. * @param by 要减少几(小于0)
  143. * @return
  144. */
  145. public long decr(String key, long delta) {
  146. if (delta < 0) {
  147. throw new RuntimeException("递减因子必须大于0");
  148. }
  149. return redisTemplate.opsForValue().increment(key, -delta);
  150. }
  151. // ================================Map=================================
  152. /**
  153. * HashGet
  154. *
  155. * @param key 键 不能为null
  156. * @param item 项 不能为null
  157. * @return 值
  158. */
  159. public Object hget(String key, String item) {
  160. return redisTemplate.opsForHash().get(key, item);
  161. }
  162. /**
  163. * 获取hashKey对应的所有键值
  164. *
  165. * @param key 键
  166. * @return 对应的多个键值
  167. */
  168. public Map<Object, Object> hmget(String key) {
  169. return redisTemplate.opsForHash().entries(key);
  170. }
  171. /**
  172. * HashSet
  173. *
  174. * @param key 键
  175. * @param map 对应多个键值
  176. * @return true 成功 false 失败
  177. */
  178. public boolean hmset(String key, Map<String, Object> map) {
  179. try {
  180. redisTemplate.opsForHash().putAll(key, map);
  181. return true;
  182. } catch (Exception e) {
  183. e.printStackTrace();
  184. return false;
  185. }
  186. }
  187. /**
  188. * HashSet 并设置时间
  189. *
  190. * @param key 键
  191. * @param map 对应多个键值
  192. * @param time 时间(秒)
  193. * @return true成功 false失败
  194. */
  195. public boolean hmset(String key, Map<String, Object> map, long time) {
  196. try {
  197. redisTemplate.opsForHash().putAll(key, map);
  198. if (time > 0) {
  199. expire(key, time);
  200. }
  201. return true;
  202. } catch (Exception e) {
  203. e.printStackTrace();
  204. return false;
  205. }
  206. }
  207. /**
  208. * 向一张hash表中放入数据,如果不存在将创建
  209. *
  210. * @param key 键
  211. * @param item 项
  212. * @param value 值
  213. * @return true 成功 false失败
  214. */
  215. public boolean hset(String key, String item, Object value) {
  216. try {
  217. redisTemplate.opsForHash().put(key, item, value);
  218. return true;
  219. } catch (Exception e) {
  220. e.printStackTrace();
  221. return false;
  222. }
  223. }
  224. /**
  225. * 向一张hash表中放入数据,如果不存在将创建
  226. *
  227. * @param key 键
  228. * @param item 项
  229. * @param value 值
  230. * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
  231. * @return true 成功 false失败
  232. */
  233. public boolean hset(String key, String item, Object value, long time) {
  234. try {
  235. redisTemplate.opsForHash().put(key, item, value);
  236. if (time > 0) {
  237. expire(key, time);
  238. }
  239. return true;
  240. } catch (Exception e) {
  241. e.printStackTrace();
  242. return false;
  243. }
  244. }
  245. /**
  246. * 删除hash表中的值
  247. *
  248. * @param key 键 不能为null
  249. * @param item 项 可以使多个 不能为null
  250. */
  251. public void hdel(String key, Object... item) {
  252. redisTemplate.opsForHash().delete(key, item);
  253. }
  254. /**
  255. * 判断hash表中是否有该项的值
  256. *
  257. * @param key 键 不能为null
  258. * @param item 项 不能为null
  259. * @return true 存在 false不存在
  260. */
  261. public boolean hHasKey(String key, String item) {
  262. return redisTemplate.opsForHash().hasKey(key, item);
  263. }
  264. /**
  265. * hash递增 如果不存在,就会创建一个 并把新增后的值返回
  266. *
  267. * @param key 键
  268. * @param item 项
  269. * @param by 要增加几(大于0)
  270. * @return
  271. */
  272. public double hincr(String key, String item, double by) {
  273. return redisTemplate.opsForHash().increment(key, item, by);
  274. }
  275. /**
  276. * hash递减
  277. *
  278. * @param key 键
  279. * @param item 项
  280. * @param by 要减少记(小于0)
  281. * @return
  282. */
  283. public double hdecr(String key, String item, double by) {
  284. return redisTemplate.opsForHash().increment(key, item, -by);
  285. }
  286. // ============================set=============================
  287. /**
  288. * 根据key获取Set中的所有值
  289. *
  290. * @param key 键
  291. * @return
  292. */
  293. public Set<Object> sGet(String key) {
  294. try {
  295. return redisTemplate.opsForSet().members(key);
  296. } catch (Exception e) {
  297. e.printStackTrace();
  298. return null;
  299. }
  300. }
  301. /**
  302. * 根据value从一个set中查询,是否存在
  303. *
  304. * @param key 键
  305. * @param value 值
  306. * @return true 存在 false不存在
  307. */
  308. public boolean sHasKey(String key, Object value) {
  309. try {
  310. return redisTemplate.opsForSet().isMember(key, value);
  311. } catch (Exception e) {
  312. e.printStackTrace();
  313. return false;
  314. }
  315. }
  316. /**
  317. * 将数据放入set缓存
  318. *
  319. * @param key 键
  320. * @param values 值 可以是多个
  321. * @return 成功个数
  322. */
  323. public long sSet(String key, Object... values) {
  324. try {
  325. return redisTemplate.opsForSet().add(key, values);
  326. } catch (Exception e) {
  327. e.printStackTrace();
  328. return 0;
  329. }
  330. }
  331. /**
  332. * 将set数据放入缓存
  333. *
  334. * @param key 键
  335. * @param time 时间(秒)
  336. * @param values 值 可以是多个
  337. * @return 成功个数
  338. */
  339. public long sSetAndTime(String key, long time, Object... values) {
  340. try {
  341. Long count = redisTemplate.opsForSet().add(key, values);
  342. if (time > 0) {
  343. expire(key, time);
  344. }
  345. return count;
  346. } catch (Exception e) {
  347. e.printStackTrace();
  348. return 0;
  349. }
  350. }
  351. /**
  352. * 获取set缓存的长度
  353. *
  354. * @param key 键
  355. * @return
  356. */
  357. public long sGetSetSize(String key) {
  358. try {
  359. return redisTemplate.opsForSet().size(key);
  360. } catch (Exception e) {
  361. e.printStackTrace();
  362. return 0;
  363. }
  364. }
  365. /**
  366. * 移除值为value的
  367. *
  368. * @param key 键
  369. * @param values 值 可以是多个
  370. * @return 移除的个数
  371. */
  372. public long setRemove(String key, Object... values) {
  373. try {
  374. Long count = redisTemplate.opsForSet().remove(key, values);
  375. return count;
  376. } catch (Exception e) {
  377. e.printStackTrace();
  378. return 0;
  379. }
  380. }
  381. // ===============================list=================================
  382. /**
  383. * 获取list缓存的内容
  384. *
  385. * @param key 键
  386. * @param start 开始
  387. * @param end 结束 0 到 -1代表所有值
  388. * @return
  389. */
  390. public List<Object> lGet(String key, long start, long end) {
  391. try {
  392. return redisTemplate.opsForList().range(key, start, end);
  393. } catch (Exception e) {
  394. e.printStackTrace();
  395. return null;
  396. }
  397. }
  398. /**
  399. * 获取list缓存的长度
  400. *
  401. * @param key 键
  402. * @return
  403. */
  404. public long lGetListSize(String key) {
  405. try {
  406. return redisTemplate.opsForList().size(key);
  407. } catch (Exception e) {
  408. e.printStackTrace();
  409. return 0;
  410. }
  411. }
  412. /**
  413. * 通过索引 获取list中的值
  414. *
  415. * @param key 键
  416. * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
  417. * @return
  418. */
  419. public Object lGetIndex(String key, long index) {
  420. try {
  421. return redisTemplate.opsForList().index(key, index);
  422. } catch (Exception e) {
  423. e.printStackTrace();
  424. return null;
  425. }
  426. }
  427. /**
  428. * 将list放入缓存
  429. *
  430. * @param key 键
  431. * @param value 值
  432. * @param time 时间(秒)
  433. * @return
  434. */
  435. public boolean lSet(String key, Object value) {
  436. try {
  437. redisTemplate.opsForList().rightPush(key, value);
  438. return true;
  439. } catch (Exception e) {
  440. e.printStackTrace();
  441. return false;
  442. }
  443. }
  444. /**
  445. * 将list放入缓存
  446. *
  447. * @param key 键
  448. * @param value 值
  449. * @param time 时间(秒)
  450. * @return
  451. */
  452. public boolean lSet(String key, Object value, long time) {
  453. try {
  454. redisTemplate.opsForList().rightPush(key, value);
  455. if (time > 0) {
  456. expire(key, time);
  457. }
  458. return true;
  459. } catch (Exception e) {
  460. e.printStackTrace();
  461. return false;
  462. }
  463. }
  464. /**
  465. * 将list放入缓存
  466. *
  467. * @param key 键
  468. * @param value 值
  469. * @param time 时间(秒)
  470. * @return
  471. */
  472. public boolean lSet(String key, List<Object> value) {
  473. try {
  474. redisTemplate.opsForList().rightPushAll(key, value);
  475. return true;
  476. } catch (Exception e) {
  477. e.printStackTrace();
  478. return false;
  479. }
  480. }
  481. /**
  482. * 将list放入缓存
  483. *
  484. * @param key 键
  485. * @param value 值
  486. * @param time 时间(秒)
  487. * @return
  488. */
  489. public boolean lSet(String key, List<Object> value, long time) {
  490. try {
  491. redisTemplate.opsForList().rightPushAll(key, value);
  492. if (time > 0) {
  493. expire(key, time);
  494. }
  495. return true;
  496. } catch (Exception e) {
  497. e.printStackTrace();
  498. return false;
  499. }
  500. }
  501. /**
  502. * 根据索引修改list中的某条数据
  503. *
  504. * @param key 键
  505. * @param index 索引
  506. * @param value 值
  507. * @return
  508. */
  509. public boolean lUpdateIndex(String key, long index, Object value) {
  510. try {
  511. redisTemplate.opsForList().set(key, index, value);
  512. return true;
  513. } catch (Exception e) {
  514. e.printStackTrace();
  515. return false;
  516. }
  517. }
  518. /**
  519. * 移除N个值为value
  520. *
  521. * @param key 键
  522. * @param count 移除多少个
  523. * @param value 值
  524. * @return 移除的个数
  525. */
  526. public long lRemove(String key, long count, Object value) {
  527. try {
  528. Long remove = redisTemplate.opsForList().remove(key, count, value);
  529. return remove;
  530. } catch (Exception e) {
  531. e.printStackTrace();
  532. return 0;
  533. }
  534. }
  535. /**
  536. * 获取指定前缀的一系列key
  537. * 使用scan命令代替keys, Redis是单线程处理,keys命令在KEY数量较多时,
  538. * 操作效率极低【时间复杂度为O(N)】,该命令一旦执行会严重阻塞线上其它命令的正常请求
  539. * @param keyPrefix
  540. * @return
  541. */
  542. private Set<String> keys(String keyPrefix) {
  543. String realKey = keyPrefix + "*";
  544. try {
  545. return redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
  546. Set<String> binaryKeys = new HashSet<>();
  547. Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(realKey).count(Integer.MAX_VALUE).build());
  548. while (cursor.hasNext()) {
  549. binaryKeys.add(new String(cursor.next()));
  550. }
  551. return binaryKeys;
  552. });
  553. } catch (Throwable e) {
  554. e.printStackTrace();
  555. }
  556. return null;
  557. }
  558. /**
  559. * 删除指定前缀的一系列key
  560. * @param keyPrefix
  561. */
  562. public void removeAll(String keyPrefix) {
  563. try {
  564. Set<String> keys = keys(keyPrefix);
  565. redisTemplate.delete(keys);
  566. } catch (Throwable e) {
  567. e.printStackTrace();
  568. }
  569. }
  570. }