PageRenderTime 163ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/jieyin/upload/utils/RedisUtils.java

https://gitlab.com/Xiaolei-Zhang/upload
Java | 389 lines | 196 code | 29 blank | 164 comment | 20 complexity | 8b0f7b7ead6ee8984e723efa076ffbbf MD5 | raw file
  1. /**
  2. * Copyright (c) 2016-2019 人人开源 All rights reserved.
  3. * <p>
  4. * https://www.renren.io
  5. * <p>
  6. * 版权所有,侵权必究!
  7. */
  8. package com.jieyin.upload.utils;
  9. import com.alibaba.fastjson.JSON;
  10. import com.alibaba.fastjson.JSONObject;
  11. import lombok.extern.slf4j.Slf4j;
  12. import org.springframework.beans.factory.annotation.Autowired;
  13. import org.springframework.data.redis.connection.RedisConnection;
  14. import org.springframework.data.redis.connection.RedisConnectionFactory;
  15. import org.springframework.data.redis.connection.RedisStringCommands;
  16. import org.springframework.data.redis.connection.ReturnType;
  17. import org.springframework.data.redis.core.*;
  18. import org.springframework.data.redis.core.types.Expiration;
  19. import org.springframework.stereotype.Component;
  20. import java.io.Serializable;
  21. import java.nio.charset.Charset;
  22. import java.util.Date;
  23. import java.util.List;
  24. import java.util.Set;
  25. import java.util.UUID;
  26. import java.util.concurrent.TimeUnit;
  27. /**
  28. * Redis工具类
  29. *
  30. * @author Mark sunlightcs@gmail.com
  31. */
  32. @Slf4j
  33. @Component
  34. public class RedisUtils {
  35. @Autowired
  36. private RedisTemplate redisTemplate;
  37. /**
  38. * 写入缓存
  39. *
  40. * @param key
  41. * @param value
  42. * @return
  43. */
  44. public boolean set(final String key, Object value) {
  45. boolean result = false;
  46. try {
  47. ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
  48. operations.set(key, value);
  49. result = true;
  50. } catch (Exception e) {
  51. e.printStackTrace();
  52. }
  53. return result;
  54. }
  55. /**
  56. * 写入缓存设置当前时间
  57. *
  58. * @param key
  59. * @param value
  60. * @param nowTime
  61. * @return
  62. */
  63. public boolean set(final String key, Object value, Long nowTime) {
  64. boolean result = false;
  65. try {
  66. ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
  67. operations.set(key, value);
  68. operations.set(key + "_setTime", String.valueOf(nowTime));
  69. result = true;
  70. } catch (Exception e) {
  71. e.printStackTrace();
  72. }
  73. return result;
  74. }
  75. /**
  76. * 写入缓存设置当前时间
  77. *
  78. * @param key
  79. * @param value
  80. * @return
  81. */
  82. public boolean setNowData(final String key, Object value) {
  83. Long nowTime = new Date().getTime();
  84. return set(key, value, nowTime);
  85. }
  86. /**
  87. * 获取缓存
  88. *
  89. * @param key
  90. * @param expireTime
  91. * @return
  92. */
  93. public Object get(final String key, Long expireTime) {
  94. Object result = null;
  95. Object setTime;
  96. Long nowTime = new Date().getTime();
  97. ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
  98. setTime = operations.get(key + "_setTime");
  99. if (setTime != null && nowTime - Long.parseLong(setTime.toString()) < expireTime) {
  100. result = operations.get(key);
  101. log.info("从redis中取出的值为:{}",result.toString());
  102. }
  103. return result;
  104. }
  105. /**
  106. * 获取缓存(有效期限制)转对象
  107. *
  108. * @param key
  109. * @param expireTime
  110. * @param clazz
  111. * @param <T>
  112. * @return
  113. */
  114. public <T> T get(final String key, Long expireTime, Class<T> clazz) {
  115. Object object = get(key, expireTime);
  116. if (object == null) {
  117. return null;
  118. } else {
  119. JSONObject jsonObject = JSONObject.parseObject(object.toString());
  120. return JSON.toJavaObject(jsonObject, clazz);
  121. }
  122. }
  123. /**
  124. * 写入缓存设置时效时间
  125. *
  126. * @param key
  127. * @param value
  128. * @return
  129. */
  130. public boolean set(final String key, Object value, Long expireTime, TimeUnit timeUnit) {
  131. boolean result = false;
  132. try {
  133. ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
  134. operations.set(key, value);
  135. redisTemplate.expire(key, expireTime, timeUnit);
  136. result = true;
  137. } catch (Exception e) {
  138. e.printStackTrace();
  139. }
  140. return result;
  141. }
  142. /**
  143. * 批量删除对应的value
  144. *
  145. * @param keys
  146. */
  147. public void remove(final String... keys) {
  148. for (String key : keys) {
  149. remove(key);
  150. }
  151. }
  152. /**
  153. * 批量删除key
  154. *
  155. * @param pattern
  156. */
  157. public void removePattern(final String pattern) {
  158. Set<Serializable> keys = redisTemplate.keys(pattern);
  159. if (keys.size() > 0) {
  160. redisTemplate.delete(keys);
  161. }
  162. }
  163. /**
  164. * 删除对应的value
  165. *
  166. * @param key
  167. */
  168. public void remove(final String key) {
  169. if (exists(key)) {
  170. redisTemplate.delete(key);
  171. }
  172. }
  173. /**
  174. * 判断缓存中是否有对应的value
  175. *
  176. * @param key
  177. * @return
  178. */
  179. public boolean exists(final String key) {
  180. return redisTemplate.hasKey(key);
  181. }
  182. /**
  183. * 读取缓存
  184. *
  185. * @param key
  186. * @return
  187. */
  188. public Object get(final String key) {
  189. Object result = null;
  190. ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
  191. result = operations.get(key);
  192. return result;
  193. }
  194. /**
  195. * 哈希 添加
  196. *
  197. * @param key
  198. * @param hashKey
  199. * @param value
  200. */
  201. public void hmSet(String key, Object hashKey, Object value) {
  202. HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
  203. hash.put(key, hashKey, value);
  204. }
  205. /**
  206. * 哈希获取数据
  207. *
  208. * @param key
  209. * @param hashKey
  210. * @return
  211. */
  212. public Object hmGet(String key, Object hashKey) {
  213. HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
  214. return hash.get(key, hashKey);
  215. }
  216. /**
  217. * 列表添加
  218. *
  219. * @param k
  220. * @param v
  221. */
  222. public void lPush(String k, Object v) {
  223. ListOperations<String, Object> list = redisTemplate.opsForList();
  224. list.rightPush(k, v);
  225. }
  226. /**
  227. * 列表获取
  228. *
  229. * @param k
  230. * @param l
  231. * @param l1
  232. * @return
  233. */
  234. public List<Object> lRange(String k, long l, long l1) {
  235. ListOperations<String, Object> list = redisTemplate.opsForList();
  236. return list.range(k, l, l1);
  237. }
  238. /**
  239. * 集合添加
  240. *
  241. * @param key
  242. * @param value
  243. */
  244. public void add(String key, Object value) {
  245. SetOperations<String, Object> set = redisTemplate.opsForSet();
  246. set.add(key, value);
  247. }
  248. /**
  249. * 集合获取
  250. *
  251. * @param key
  252. * @return
  253. */
  254. public Set<Object> setMembers(String key) {
  255. SetOperations<String, Object> set = redisTemplate.opsForSet();
  256. return set.members(key);
  257. }
  258. /**
  259. * 有序集合添加
  260. *
  261. * @param key
  262. * @param value
  263. * @param scoure
  264. */
  265. public void zAdd(String key, Object value, double scoure) {
  266. ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
  267. zset.add(key, value, scoure);
  268. }
  269. /**
  270. * 有序集合获取
  271. *
  272. * @param key
  273. * @param scoure
  274. * @param scoure1
  275. * @return
  276. */
  277. public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
  278. ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
  279. return zset.rangeByScore(key, scoure, scoure1);
  280. }
  281. /**
  282. * 解锁脚本,原子操作
  283. */
  284. private static final String unlockScript =
  285. "if redis.call(\"get\",KEYS[1]) == ARGV[1]\n"
  286. + "then\n"
  287. + " return redis.call(\"del\",KEYS[1])\n"
  288. + "else\n"
  289. + " return 0\n"
  290. + "end";
  291. /**
  292. * 加锁,有阻塞
  293. *
  294. * @param name
  295. * @param expire
  296. * @param timeout
  297. * @return
  298. */
  299. public String lock(String name, long expire, long timeout) {
  300. long startTime = System.currentTimeMillis();
  301. String token;
  302. do {
  303. token = tryLock(name, expire);
  304. if (token == null) {
  305. if ((System.currentTimeMillis() - startTime) > (timeout - 50))
  306. break;
  307. try {
  308. Thread.sleep(50); //try 50 per sec
  309. } catch (InterruptedException e) {
  310. e.printStackTrace();
  311. return null;
  312. }
  313. }
  314. } while (token == null);
  315. return token;
  316. }
  317. /**
  318. * 加锁,无阻塞
  319. *
  320. * @param name
  321. * @param expire
  322. * @return
  323. */
  324. public String tryLock(String name, long expire) {
  325. String token = UUID.randomUUID().toString();
  326. RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
  327. RedisConnection conn = factory.getConnection();
  328. try {
  329. Boolean result = conn.set(name.getBytes(Charset.forName("UTF-8")), token.getBytes(Charset.forName("UTF-8")),
  330. Expiration.from(expire, TimeUnit.MILLISECONDS), RedisStringCommands.SetOption.SET_IF_ABSENT);
  331. if (result != null && result)
  332. return token;
  333. } finally {
  334. RedisConnectionUtils.releaseConnection(conn, factory);
  335. }
  336. return null;
  337. }
  338. /**
  339. * 解锁
  340. *
  341. * @param name
  342. * @param token
  343. * @return
  344. */
  345. public boolean unlock(String name, String token) {
  346. byte[][] keysAndArgs = new byte[2][];
  347. keysAndArgs[0] = name.getBytes(Charset.forName("UTF-8"));
  348. keysAndArgs[1] = token.getBytes(Charset.forName("UTF-8"));
  349. RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
  350. RedisConnection conn = factory.getConnection();
  351. try {
  352. Long result = conn.scriptingCommands().eval(unlockScript.getBytes(Charset.forName("UTF-8")), ReturnType.INTEGER, 1, keysAndArgs);
  353. if (result != null && result > 0)
  354. return true;
  355. } finally {
  356. RedisConnectionUtils.releaseConnection(conn, factory);
  357. }
  358. return false;
  359. }
  360. }