RedisCacheGateway.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. package com.smppw.analysis.infrastructure.gatewayimpl;
  2. import cn.hutool.core.map.MapUtil;
  3. import cn.hutool.core.util.StrUtil;
  4. import cn.hutool.json.JSONUtil;
  5. import com.smppw.analysis.domain.gateway.CacheFactory;
  6. import com.smppw.analysis.domain.gateway.CacheGateway;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.dao.DataAccessException;
  9. import org.springframework.data.redis.connection.RedisConnection;
  10. import org.springframework.data.redis.core.HashOperations;
  11. import org.springframework.data.redis.core.RedisCallback;
  12. import org.springframework.data.redis.core.RedisTemplate;
  13. import org.springframework.data.redis.hash.HashMapper;
  14. import org.springframework.data.redis.hash.Jackson2HashMapper;
  15. import org.springframework.stereotype.Component;
  16. import org.springframework.util.CollectionUtils;
  17. import java.util.*;
  18. import java.util.concurrent.TimeUnit;
  19. @Component(CacheFactory.REDIS)
  20. public class RedisCacheGateway implements CacheGateway<Object> {
  21. private final RedisTemplate<String, Object> _redisTemplate;
  22. private final HashOperations<String, String, Object> _hashOperations;
  23. private final HashMapper<Object, String, Object> _hashMapper;
  24. public RedisCacheGateway(@Autowired(required = false) RedisTemplate<String, Object> _redisTemplate) {
  25. this._redisTemplate = _redisTemplate;
  26. this._hashOperations = _redisTemplate == null ? null : _redisTemplate.opsForHash();
  27. this._hashMapper = new Jackson2HashMapper(true);
  28. }
  29. // =============================common============================
  30. /**
  31. * 指定缓存失效时间
  32. *
  33. * @param key 键
  34. * @param time 时间(秒)
  35. * @return /
  36. */
  37. public boolean expire(String key, long time, TimeUnit timeUnit) {
  38. try {
  39. if (time > 0) {
  40. _redisTemplate.expire(key, time, timeUnit);
  41. }
  42. return true;
  43. } catch (Exception e) {
  44. e.printStackTrace();
  45. return false;
  46. }
  47. }
  48. /**
  49. * 根据key 获取过期时间
  50. *
  51. * @param key 键 不能为null
  52. * @return 时间(秒) 返回0代表为永久有效
  53. */
  54. public Long getExpire(String key) {
  55. return _redisTemplate.getExpire(key, TimeUnit.SECONDS);
  56. }
  57. /**
  58. * 判断key是否存在
  59. *
  60. * @param key 键
  61. * @return true 存在 false不存在
  62. */
  63. public Boolean hasKey(String key) {
  64. if (StrUtil.isBlank(key)) {
  65. return false;
  66. }
  67. return _redisTemplate.hasKey(key);
  68. }
  69. @Override
  70. public void delete(List<String> keys) {
  71. if (keys != null && keys.size() > 0) {
  72. if (keys.size() == 1) {
  73. _redisTemplate.delete(keys.get(0));
  74. } else {
  75. _redisTemplate.delete(keys);
  76. }
  77. }
  78. }
  79. /**
  80. * 删除缓存
  81. *
  82. * @param key 可以传一个值 或多个
  83. */
  84. @SuppressWarnings("unchecked")
  85. public void delete(String... key) {
  86. if (key != null && key.length > 0) {
  87. if (key.length == 1) {
  88. _redisTemplate.delete(key[0]);
  89. } else {
  90. _redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
  91. }
  92. }
  93. }
  94. // ============================String=============================
  95. /**
  96. * 普通缓存获取
  97. *
  98. * @param key 键
  99. * @return 值
  100. */
  101. public Object get(String key) {
  102. return key == null ? null : _redisTemplate.opsForValue().get(key);
  103. }
  104. /**
  105. * 获取hashKey对应的所有键值
  106. *
  107. * @param key 键
  108. * @return 对应的多个键值
  109. */
  110. public <T> T get(String key, Class<T> pValClass) {
  111. Object rtn = _redisTemplate.opsForValue().get(key);
  112. if (null == rtn) {
  113. return null;
  114. }
  115. if (rtn.getClass().equals(pValClass)) {
  116. return (T) rtn;
  117. } else if (rtn instanceof Map) {
  118. return JSONUtil.toBean(JSONUtil.toJsonStr(rtn), pValClass);
  119. } else if (rtn instanceof String) {
  120. return JSONUtil.toBean((String) rtn, pValClass);
  121. } else {
  122. return null;
  123. }
  124. }
  125. /**
  126. * 普通缓存放入
  127. *
  128. * @param key 键
  129. * @param value 值
  130. * @return true成功 false失败
  131. */
  132. public boolean set(String key, Object value) {
  133. try {
  134. _redisTemplate.opsForValue().set(key, value);
  135. return true;
  136. } catch (Exception e) {
  137. e.printStackTrace();
  138. return false;
  139. }
  140. }
  141. public boolean set(String key, Object value, long ttl, TimeUnit timeUnit) {
  142. try {
  143. _redisTemplate.opsForValue().set(key, value, ttl, timeUnit);
  144. return true;
  145. } catch (Exception e) {
  146. e.printStackTrace();
  147. return false;
  148. }
  149. }
  150. /**
  151. * Description: 如果key存在, 则返回false, 如果不存在,
  152. * 则将key=value放入redis中, 并返回true
  153. *
  154. * @param
  155. * @return
  156. * @author: bixuejun(bxjgood @ 163.com)
  157. * @date: 2021/11/26 14:36
  158. */
  159. public Boolean setIfAbsent(String key, String value) {
  160. return _redisTemplate.opsForValue().setIfAbsent(key, value);
  161. }
  162. /**
  163. * 普通缓存放入并设置时间
  164. *
  165. * @param key 键
  166. * @param value 值
  167. * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
  168. * @return true成功 false 失败
  169. */
  170. public boolean set(String key, Object value, long time) {
  171. try {
  172. if (time > 0) {
  173. _redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
  174. } else {
  175. set(key, value);
  176. }
  177. return true;
  178. } catch (Exception e) {
  179. e.printStackTrace();
  180. return false;
  181. }
  182. }
  183. /**
  184. * 递增
  185. *
  186. * @param key 键
  187. * @param delta 要增加几(大于0)
  188. * @return
  189. */
  190. public Long increment(String key, long delta) {
  191. if (delta < 0) {
  192. throw new RuntimeException("递增因子必须大于0");
  193. }
  194. return _redisTemplate.opsForValue().increment(key, delta);
  195. }
  196. /**
  197. * 递减
  198. *
  199. * @param key 键
  200. * @param delta 要减少几(小于0)
  201. * @return
  202. */
  203. public Long decrement(String key, long delta) {
  204. if (delta < 0) {
  205. throw new RuntimeException("递减因子必须大于0");
  206. }
  207. return _redisTemplate.opsForValue().decrement(key, delta);
  208. }
  209. // ================================Map=================================
  210. @Override
  211. public boolean hset(String key, Map<String, Object> values) {
  212. try {
  213. _redisTemplate.opsForHash().putAll(key, values);
  214. return true;
  215. } catch (Exception e) {
  216. e.printStackTrace();
  217. return false;
  218. }
  219. }
  220. /**
  221. * HashGet
  222. *
  223. * @param key 键 不能为null
  224. * @param item 项 不能为null
  225. * @return 值
  226. */
  227. public Object hget(String key, String item) {
  228. return _redisTemplate.opsForHash().get(key, item);
  229. }
  230. /**
  231. * 获取hashKey对应的所有键值
  232. *
  233. * @param key 键
  234. * @return 对应的多个键值
  235. */
  236. public Map<String, Object> hget(String key) {
  237. return _redisTemplate.<String, Object>opsForHash().entries(key);
  238. }
  239. @Override
  240. public List<Object> hget(String key, Collection<String> item) {
  241. return _hashOperations.multiGet(key, item);
  242. }
  243. /**
  244. * 获取hashKey对应的所有键值
  245. *
  246. * @param key 键
  247. * @return 对应的多个键值
  248. */
  249. public <T> Map<String, T> hmget(String key, Class<T> pValClass) {
  250. Map<Object, Object> rtn = _redisTemplate.opsForHash().entries(key);
  251. Map<String, T> result = MapUtil.newHashMap();
  252. for (Map.Entry<Object, Object> data : rtn.entrySet()) {
  253. String subKey = data.getKey().toString();
  254. T value = JSONUtil.toBean(JSONUtil.toJsonStr(data.getValue()), pValClass);
  255. result.put(subKey, value);
  256. }
  257. return result;
  258. }
  259. /**
  260. * 使用hget获取Redis对象
  261. *
  262. * @param key 键
  263. * @return 返回对象
  264. */
  265. public <T> T hmgetObj(String key) {
  266. Map<String, Object> mpData = _hashOperations.entries(key);
  267. if (mpData.size() == 0) {
  268. return null;
  269. }
  270. return (T) _hashMapper.fromHash(mpData);
  271. }
  272. /**
  273. * HashSet
  274. *
  275. * @param key 键
  276. * @param map 对应多个键值
  277. * @return true 成功 false 失败
  278. */
  279. public boolean hmset(String key, Map<String, Object> map) {
  280. try {
  281. _redisTemplate.opsForHash().putAll(key, map);
  282. return true;
  283. } catch (Exception e) {
  284. e.printStackTrace();
  285. return false;
  286. }
  287. }
  288. /**
  289. * 使用hset对指定键放入对象的所有值
  290. *
  291. * @param key 键
  292. * @param v_obj 对象
  293. * @param <T>对象类型
  294. * @return 是否成功
  295. */
  296. public <T> boolean hmsetObject(String key, T v_obj) {
  297. try {
  298. Map<String, Object> mappedHash = _hashMapper.toHash(v_obj);
  299. _hashOperations.putAll(key, mappedHash);
  300. return true;
  301. } catch (Exception e) {
  302. e.printStackTrace();
  303. return false;
  304. }
  305. }
  306. // /**
  307. // * HashSet 并设置时间
  308. // *
  309. // * @param key 键
  310. // * @param map 对应多个键值
  311. // * @param time 时间(秒)
  312. // * @return true成功 false失败
  313. // */
  314. // public boolean hmset(String key, Map<String, Object> map, long time) {
  315. // try {
  316. // _redisTemplate.opsForHash().putAll(key, map);
  317. // if (time > 0) {
  318. // expire(key, time);
  319. // }
  320. // return true;
  321. // } catch (Exception e) {
  322. // e.printStackTrace();
  323. // return false;
  324. // }
  325. // }
  326. //
  327. // /**
  328. // * 使用hset对指定键放入对象的所有值,并设置过期时间
  329. // *
  330. // * @param key 键
  331. // * @param v_obj 对象
  332. // * @param <T>对象类型
  333. // * @return 是否成功
  334. // */
  335. // public <T> boolean hmsetObject(String key, T v_obj, long time) {
  336. // try {
  337. // Map<String, Object> mappedHash = _hashMapper.toHash(v_obj);
  338. // _hashOperations.putAll(key, mappedHash);
  339. // if (time > 0) {
  340. // expire(key, time);
  341. // }
  342. // return true;
  343. // } catch (Exception e) {
  344. // e.printStackTrace();
  345. // return false;
  346. // }
  347. // }
  348. /**
  349. * 向一张hash表中放入数据,如果不存在将创建
  350. *
  351. * @param key 键
  352. * @param item 项
  353. * @param value 值
  354. * @return true 成功 false失败
  355. */
  356. public boolean hset(String key, String item, Object value) {
  357. try {
  358. _redisTemplate.opsForHash().put(key, item, value);
  359. return true;
  360. } catch (Exception e) {
  361. e.printStackTrace();
  362. return false;
  363. }
  364. }
  365. /**
  366. * 向一张hash表中放入数据,如果不存在将创建
  367. *
  368. * @param key 键
  369. * @param item 项
  370. * @param value 值
  371. * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
  372. * @return true 成功 false失败
  373. */
  374. public boolean hset(String key, String item, Object value, long time, TimeUnit timeUnit) {
  375. try {
  376. _redisTemplate.opsForHash().put(key, item, value);
  377. if (time > 0) {
  378. expire(key, time, timeUnit);
  379. }
  380. return true;
  381. } catch (Exception e) {
  382. e.printStackTrace();
  383. return false;
  384. }
  385. }
  386. /**
  387. * 删除hash表中的值
  388. *
  389. * @param key 键 不能为null
  390. * @param item 项 可以使多个 不能为null
  391. */
  392. public void hdel(String key, Object... item) {
  393. _redisTemplate.opsForHash().delete(key, item);
  394. }
  395. /**
  396. * 判断hash表中是否有该项的值
  397. *
  398. * @param key 键 不能为null
  399. * @param item 项 不能为null
  400. * @return true 存在 false不存在
  401. */
  402. public boolean hHasKey(String key, String item) {
  403. return _redisTemplate.opsForHash().hasKey(key, item);
  404. }
  405. /**
  406. * hash递增 如果不存在,就会创建一个 并把新增后的值返回
  407. *
  408. * @param key 键
  409. * @param item 项
  410. * @param by 要增加几(大于0)
  411. * @return
  412. */
  413. public double hincr(String key, String item, double by) {
  414. return _redisTemplate.opsForHash().increment(key, item, by);
  415. }
  416. /**
  417. * hash递减
  418. *
  419. * @param key 键
  420. * @param item 项
  421. * @param by 要减少记(小于0)
  422. * @return
  423. */
  424. public double hdecr(String key, String item, double by) {
  425. return _redisTemplate.opsForHash().increment(key, item, -by);
  426. }
  427. // ============================set=============================
  428. /**
  429. * 根据key获取Set中的所有值
  430. *
  431. * @param key 键
  432. * @return
  433. */
  434. public Set<Object> sGet(String key) {
  435. try {
  436. return _redisTemplate.opsForSet().members(key);
  437. } catch (Exception e) {
  438. e.printStackTrace();
  439. return null;
  440. }
  441. }
  442. /**
  443. * 根据value从一个set中查询,是否存在
  444. *
  445. * @param key 键
  446. * @param value 值
  447. * @return true 存在 false不存在
  448. */
  449. public Boolean sHasKey(String key, Object value) {
  450. try {
  451. return _redisTemplate.opsForSet().isMember(key, value);
  452. } catch (Exception e) {
  453. e.printStackTrace();
  454. return false;
  455. }
  456. }
  457. /**
  458. * 将数据放入set缓存
  459. *
  460. * @param key 键
  461. * @param values 值 可以是多个
  462. * @return 成功个数
  463. */
  464. public Long sSet(String key, Object... values) {
  465. try {
  466. return _redisTemplate.opsForSet().add(key, values);
  467. } catch (Exception e) {
  468. e.printStackTrace();
  469. return 0L;
  470. }
  471. }
  472. // /**
  473. // * 将set数据放入缓存
  474. // *
  475. // * @param key 键
  476. // * @param time 时间(秒)
  477. // * @param values 值 可以是多个
  478. // * @return 成功个数
  479. // */
  480. // public Long sSetAndTime(String key, long time, Object... values) {
  481. // try {
  482. // Long count = _redisTemplate.opsForSet().add(key, values);
  483. // if (time > 0) {
  484. // expire(key, time);
  485. // }
  486. // return count;
  487. // } catch (Exception e) {
  488. // e.printStackTrace();
  489. // return 0L;
  490. // }
  491. // }
  492. /**
  493. * 获取set缓存的长度
  494. *
  495. * @param key 键
  496. * @return
  497. */
  498. public Long sGetSetSize(String key) {
  499. try {
  500. return _redisTemplate.opsForSet().size(key);
  501. } catch (Exception e) {
  502. e.printStackTrace();
  503. return 0L;
  504. }
  505. }
  506. /**
  507. * 移除值为value的
  508. *
  509. * @param key 键
  510. * @param values 值 可以是多个
  511. * @return 移除的个数
  512. */
  513. public Long setRemove(String key, Object... values) {
  514. try {
  515. return _redisTemplate.opsForSet().remove(key, values);
  516. } catch (Exception e) {
  517. e.printStackTrace();
  518. return 0L;
  519. }
  520. }
  521. // ===============================list=================================
  522. /**
  523. * 获取list缓存的内容
  524. *
  525. * @param key 键
  526. * @param start 开始
  527. * @param end 结束 0 到 -1代表所有值
  528. * @return
  529. */
  530. public List<Object> lGet(String key, long start, long end) {
  531. try {
  532. return _redisTemplate.opsForList().range(key, start, end);
  533. } catch (Exception e) {
  534. e.printStackTrace();
  535. return null;
  536. }
  537. }
  538. /**
  539. * 获取list缓存的长度
  540. *
  541. * @param key 键
  542. * @return
  543. */
  544. public Long getListSize(String key) {
  545. try {
  546. return _redisTemplate.opsForList().size(key);
  547. } catch (Exception e) {
  548. e.printStackTrace();
  549. return 0L;
  550. }
  551. }
  552. /**
  553. * 通过索引 获取list中的值
  554. *
  555. * @param key 键
  556. * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
  557. * @return
  558. */
  559. public Object listGet(String key, long index) {
  560. try {
  561. return _redisTemplate.opsForList().index(key, index);
  562. } catch (Exception e) {
  563. e.printStackTrace();
  564. return null;
  565. }
  566. }
  567. /**
  568. * 根据索引修改list中的某条数据
  569. *
  570. * @param key 键
  571. * @param index 索引
  572. * @param value 值
  573. * @return
  574. */
  575. public boolean listSet(String key, long index, Object value) {
  576. try {
  577. _redisTemplate.opsForList().set(key, index, value);
  578. return true;
  579. } catch (Exception e) {
  580. e.printStackTrace();
  581. return false;
  582. }
  583. }
  584. /**
  585. * 把值放入队尾
  586. *
  587. * @param key 键
  588. * @param value 值
  589. * @return
  590. */
  591. public boolean rPush(String key, Object value) {
  592. try {
  593. _redisTemplate.opsForList().rightPush(key, value);
  594. return true;
  595. } catch (Exception e) {
  596. e.printStackTrace();
  597. return false;
  598. }
  599. }
  600. /**
  601. * 把值放入队首
  602. *
  603. * @param key 键
  604. * @param value 值
  605. * @return
  606. */
  607. public boolean lPush(String key, Object value) {
  608. try {
  609. _redisTemplate.opsForList().leftPush(key, value);
  610. return true;
  611. } catch (Exception e) {
  612. e.printStackTrace();
  613. return false;
  614. }
  615. }
  616. /**
  617. * 批量插入队尾
  618. *
  619. * @param key
  620. * @param value
  621. * @return
  622. */
  623. public boolean rPushAll(String key, List<Object> value) {
  624. try {
  625. _redisTemplate.opsForList().rightPushAll(key, value);
  626. return true;
  627. } catch (Exception e) {
  628. e.printStackTrace();
  629. return false;
  630. }
  631. }
  632. /**
  633. * 批量插入队首
  634. *
  635. * @param key
  636. * @param value
  637. * @return
  638. */
  639. public boolean lPushAll(String key, List<Object> value) {
  640. try {
  641. _redisTemplate.opsForList().leftPushAll(key, value);
  642. return true;
  643. } catch (Exception e) {
  644. e.printStackTrace();
  645. return false;
  646. }
  647. }
  648. /**
  649. * 从队首推出一个元素
  650. *
  651. * @param key 键
  652. * @return 队首元素
  653. */
  654. public Object lPop(String key) {
  655. try {
  656. return _redisTemplate.opsForList().leftPop(key);
  657. } catch (Exception e) {
  658. e.printStackTrace();
  659. return null;
  660. }
  661. }
  662. /**
  663. * 从队尾推出一个元素
  664. *
  665. * @param key 键
  666. * @return 队首元素
  667. */
  668. public Object rPop(String key) {
  669. try {
  670. return _redisTemplate.opsForList().rightPop(key);
  671. } catch (Exception e) {
  672. e.printStackTrace();
  673. return null;
  674. }
  675. }
  676. /*********************************pipeline*****************/
  677. public <T> List<Object> executePipelined(RedisCallback<T> pFnCallBack) {
  678. return _redisTemplate.executePipelined(pFnCallBack, _redisTemplate.getValueSerializer());
  679. }
  680. public List<String> keys(String pPattern) {
  681. return new ArrayList<>(Objects.requireNonNull(_redisTemplate.keys(pPattern)));
  682. }
  683. public void batchRemove(List<String> pKeyList) {
  684. new RedisCallback<Integer>() {
  685. @Override
  686. public Integer doInRedis(RedisConnection connection) throws DataAccessException {
  687. connection.openPipeline();
  688. for (String key : pKeyList) {
  689. connection.expire(key.getBytes(), 1);
  690. }
  691. return 0;
  692. }
  693. };
  694. }
  695. }