redis的封装

```java public class RedisUtil implements ICache { private static final Logger logger = LoggerFactory.getLogger(RedisUtil.class); @Autowired protected RedisTemplate<String, String> redisTemplate; /** * 队列操作 从队列左边放入 * * @param queueName 键名称 * @param value 对象值 * @return */ @Override public <T extends Object> boolean lPush(final String queueName, final T value) { return redisTemplate.execute((RedisCallback<Boolean>)connection -> { connection.lPush(queueName.getBytes(), serialize(value)); return true; }); } /** * 从队列右边取出 * * @param queueName 键名称 * @param <T> 对象类型 * @return */ @Override public <T extends Object> T rPop(final String queueName) { return redisTemplate.execute((RedisCallback<T>)connection -> { byte[] value = connection.rPop(queueName.getBytes()); return value == null ? null : (T)unSerialize(value); }); } /** * 获取队列长度 * * @param queueName 键名称 * @return */ @Override public Long lLen(final String queueName) { return redisTemplate.execute((RedisCallback<Long>)connection -> { Long value = connection.lLen(queueName.getBytes()); return value == null ? null : value; }); } @Override /** * 获取一个范围的数组 * @param queueName * @param <T> * @return */ public <T extends Object> T lRang(final String queueName) { return redisTemplate.execute((RedisCallback<T>)connection -> { List<byte[]> value = connection.lRange(queueName.getBytes(), 0L, -1L); if (value == null) { return null; } List list = new ArrayList(); for (byte[] byts : value) { list.add(unSerialize(byts)); } return (T)list; }); } /** * 封装redis的set方法,用于专门设置一个String类型缓存 * * @param key 键名称 * @param value 值 * @return */ @Override public boolean setString(final String key, final String value) { return redisTemplate.execute((RedisCallback<Boolean>)connection -> { connection.set(key.getBytes(), value.getBytes()); return true; }); } /** * 封装redis的set方法,用于专门设置一个String类型缓存 * * @param key 键名称 * @param value 值 * @param timeout 超时时长 * @param timeUnit 超时时长单位 * @return */ @Override public boolean setString(final String key, final String value, long timeout, TimeUnit timeUnit) { boolean r1 = redisTemplate.execute((RedisCallback<Boolean>)connection -> { connection.set(key.getBytes(), value.getBytes()); return true; }); boolean r2 = setExpire(key, timeout, timeUnit); return r1 && r2; } /** * 封装redis的get方法,用于获取一个String类型缓存 * * @param key 键名称 * @return String类型值 */ @Override public String getString(final String key) { return redisTemplate.execute((RedisCallback<String>)connection -> { byte[] value = connection.get(key.getBytes()); return value == null ? null : new String(value); }); } /** * 缓存一个对象数据 * * @param key 键名称 * @param value 对象值 * @return */ @Override public <T extends Object> boolean setObject(final String key, final T value) { return redisTemplate.execute((RedisCallback<Boolean>)connection -> { connection.set(key.getBytes(), serialize(value)); return true; }); } /** * 缓存一个对象数据 * * @param key 键名称 * @param value 对象值 * @param timeout * @param timeUnit * @return */ @Override public boolean setObject(final String key, final Object value, long timeout, TimeUnit timeUnit) { boolean r1 = redisTemplate.execute((RedisCallback<Boolean>)connection -> { connection.set(key.getBytes(), serialize(value)); return true; }); boolean r2 = setExpire(key, timeout, timeUnit); return r1 && r2; } /** * 获取一个对象数据 * * @param key 键名称 * @param <T> 对象类型 * @return */ @Override public <T extends Object> T getObject(final String key) { return redisTemplate.execute((RedisCallback<T>)connection -> { byte[] value = connection.get(key.getBytes()); return value == null ? null : (T)unSerialize(value); }); } /** * 删除一个redis缓存 * * @param key * @return */ @Override public long deleteKey(final String key) { return redisTemplate.execute((RedisCallback<Long>)connection -> connection.del(key.getBytes())); } /** * 将对象转换为字节数组 * * @param object 对象 * @return */ <T extends Object> byte[] serialize(T object) { try { //序列化 ByteArrayOutputStream bao = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bao); oos.writeObject(object); return bao.toByteArray(); } catch (Exception e) { logger.error(e.getMessage(), e); throw new RuntimeException(e.getMessage(), e); } } /** * 将字节数组转换为对象 * * @param bytes * @return */ <T extends Object> T unSerialize(byte[] bytes) { try { //反序列化 ByteArrayInputStream bao = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bao); return (T)ois.readObject(); } catch (Exception e) { logger.error(e.getMessage(), e); throw new RuntimeException(e.getMessage(), e); } } /** * 设置一个缓存的过期 * * @param key * @param timeout * @param timeUnit * @return */ @Override public boolean setExpire(String key, long timeout, TimeUnit timeUnit) { return redisTemplate.expire(key, timeout, timeUnit); } /** * 设置一个根据业务进行区分的key * * @param value 值 * @param timeout 有效时长 * @param timeUnit 时间类型 * @param keys key 类似于biz,userId,XXXXXX 实际存入biz:userId:XXXXXX * @return */ @Override public boolean setString(String value, long timeout, TimeUnit timeUnit, String... keys) { if (keys == null || keys.length < 1) { return false; } final String key = CommonUtils.produceKey(keys); return this.setString(key, value, timeout, timeUnit); } /** * 缓存一个有超时时长的数据 * * @param value * @param timeout * @param timeUnit * @param keys key 类似于biz,userId,XXXXXX 实际存入biz:userId:XXXXXX * @return */ @Override public <T> boolean setObject(T value, long timeout, TimeUnit timeUnit, String... keys) { if (keys == null || keys.length < 1) { return false; } final String key = CommonUtils.produceKey(keys); return this.setObject(key, value, timeout, timeUnit); } /** * redis提供的setNX函数,具有互斥的性质,可以用来设置一个标记判断唯一操作,值与key想通 * * @param key 键名称,需要唯一 * @param value 值 * @return */ @Override public boolean setNX(String key, String value) { return redisTemplate.execute( (RedisCallback<Boolean>)connection -> connection.setNX((key).getBytes(), value.getBytes())); } /** * redis提供的setNX函数,具有互斥的性质,可以用来设置一个标记判断唯一操作 * * @param key 键名称,需要唯一 * @param value 值 * @param timeout 超时时长 * @param timeUnit 超时时长单位 * @return */ @Override public boolean setNX(final String key, final String value, long timeout, TimeUnit timeUnit) { boolean r1 = redisTemplate.execute( (RedisCallback<Boolean>)connection -> connection.setNX((key).getBytes(), value.getBytes())); boolean r2 = setExpire(key, timeout, timeUnit); return r1 && r2; } @Override public long getIncr(String key, long timeout, TimeUnit timeUnit) { RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); Long increment = entityIdCounter.getAndIncrement(); //初始设置过期时间 if (null == increment || increment.longValue() == 0) { setExpire(key, timeout, timeUnit); } return increment; } @Override public long getIncr(String key) { return new RedisAtomicLong(key, redisTemplate.getConnectionFactory()).getAndIncrement(); } @Override /** * 获取指定key的到期时间 * @param key * @param timeUnit * @return */ public long getTTL(String key, TimeUnit timeUnit) { return redisTemplate.getExpire(key, timeUnit); } @Override /** * 获取指定key的到期时间 默认分组 * @param key * @return */ public long getTTL(String key) { return getTTL(key, TimeUnit.SECONDS); } /** * 将列表存入HASH * * @param orgId -机构ID * @param redisTypeEnum -字典类型(包含散列名称,key-value中key对应的实体字段) * @param collection -对象列表 * @return */ @Override public boolean hashMultiSet(RedisTypeEnum redisTypeEnum, Collection<?> collection, Long orgId) { String hashKey = redisTypeEnum.getHashKey(); String keyType = redisTypeEnum.getKeyType(); if (StringUtils.isBlank(hashKey) || StringUtils.isBlank(keyType) || collection == null || collection .isEmpty()) { return false; } if (!Objects.isNull(orgId)) { hashKey = CommonUtils.produceKey(orgId + "", hashKey); } //指定map初始容量为集合容量 Map<String, String> map = new HashMap<>(Double.valueOf(collection.size() / 0.75 + 1).intValue()); collection.forEach(c -> { map.put(this.getKeyTypeValue(keyType, c), JSON.toJSONString(c)); }); // 增加缓存过期时间,目前数据库清了,缓存没清,缓存就会产生脏数据。 redisTemplate.expire(hashKey, 480, TimeUnit.MINUTES); redisTemplate.opsForHash().putAll(hashKey, map); return true; } /** * 获取多个指定对象tclass,散列为hashKey下的多个key的对象集合 * * @param redisTypeEnum 字典类型(包含散列名称,key-value中key对应的实体字段) * @param tClass 对象class * @param keys key列表 can not be null && empty * @param <T> * @return 指定对象T的集合列表 */ @Override public <T> List<T> hashMultiGet(RedisTypeEnum redisTypeEnum, Class<T> tClass, List<String> keys, Long orgId) { String hashKey = redisTypeEnum.getHashKey(); if (StringUtils.isBlank(hashKey) || Objects.isNull(tClass) || Objects.isNull(keys) || keys.size() < 1) { return new ArrayList<>(); } if (orgId != null) { hashKey = CommonUtils.produceKey(orgId + "", hashKey); } try { List<T> list = new ArrayList<>(); List<Object> objects = redisTemplate.opsForHash().multiGet(hashKey, Arrays.asList(keys.toArray())); if (objects != null && !objects.isEmpty()) { for (Object obj : objects) { if (Objects.isNull(obj)) { continue; } String text = CommonUtils.covert(obj); T t1 = JSON.parseObject(text, tClass); list.add(t1); } } return list; } catch (Exception e) { logger.error(e.getMessage(), e); } return null; } /** * 获取指定对象tclass,散列为hashKey下的key的对象 * * @param redisTypeEnum 字典类型(包含散列名称,key-value中key对应的实体字段) * @param tClass 对象class * @param key key * @return */ @Override public <T> T hashGet(RedisTypeEnum redisTypeEnum, Class<T> tClass, String key, Long orgId) { String hashKey = redisTypeEnum.getHashKey(); if (StringUtils.isBlank(hashKey) || Objects.isNull(tClass) || StringUtils.isBlank(key)) { return null; } List<String> keys = new ArrayList<>(); keys.add(key); List<T> list = this.hashMultiGet(redisTypeEnum, tClass, keys, orgId); if (!Objects.isNull(list) && !list.isEmpty()) { return list.get(0); } return null; } @Override public String getSerialNumber(Long orgId, SerialNumberTypeEnum serialNumberTypeEnum, SerialNumberMethodEnum serialNumberMethodEnum) { if (!ObjectUtils.allNotNull(orgId, serialNumberMethodEnum, serialNumberTypeEnum)) { return null; } // 生成规则:yyMMdd001 年后两位+月+日+3位递增号 每天清零 if (SerialNumberMethodEnum.SER_Method_0001.equals(serialNumberMethodEnum)) { return serMethod001(orgId, serialNumberTypeEnum); } else if (SerialNumberMethodEnum.SER_Method_0002.equals(serialNumberMethodEnum)) { return serMethod002(orgId, serialNumberTypeEnum); } else if (SerialNumberMethodEnum.SER_Method_0003.equals(serialNumberMethodEnum)) { return serMethod003(orgId, serialNumberTypeEnum); } else if (SerialNumberMethodEnum.SER_Method_0004.equals(serialNumberMethodEnum)) { return serMethod004(orgId, serialNumberTypeEnum); } else if (SerialNumberMethodEnum.SER_Method_0005.equals(serialNumberMethodEnum)) { return serMethod005(orgId, serialNumberTypeEnum); } return null; } /** * 生成规则:yyMMdd001 年后两位+月+日+3位递增号 每天清零 * * @param orgId 机构ID * @param serialNumberTypeEnum 序列号类型 * @return 序列号 */ private String serMethod001(Long orgId, SerialNumberTypeEnum serialNumberTypeEnum) { Date date = new Date(); // 设置失效类型(yyyyMMdd为:每天失效,yyyyMM为:每月失效,yyyy为:每年失效,不要下段代码为:永久有效) SimpleDateFormat redisKey = new SimpleDateFormat("yyyyMMdd"); // redis上保存的KEY (将日期拼接到KEY里,保存第二天获取的是新的) String key = "SerialNum:" + redisKey.format(date) + "_" + serialNumberTypeEnum + "_" + orgId; // 设置过期类型(24 数量, TimeUnit 单位)此处需要与上面相对应 long serNum = getIncr(key, 24, TimeUnit.HOURS); // reids取序号从0开始,需要加1 serNum = serNum + 1; SimpleDateFormat sf = new SimpleDateFormat("yyMMdd"); final Long maxNum = 999L; if (serNum > maxNum) { return sf.format(new Date()); } return sf.format(date) + StringUtils.leftPad(serNum + "", 3, "0"); } /** * 生成规则:生成规则:yyyyMMdd00001 四位年+月+日+5位递增号 每天清零 * * @param orgId 机构ID * @param serialNumberTypeEnum 序列号类型 * @return 序列号 */ private String serMethod002(Long orgId, SerialNumberTypeEnum serialNumberTypeEnum) { Date date = new Date(); // 设置失效类型(yyyyMMdd为:每天失效,yyyyMM为:每月失效,yyyy为:每年失效,不要下段代码为:永久有效) SimpleDateFormat redisKey = new SimpleDateFormat("yyyyMMdd"); // redis上保存的KEY (将日期拼接到KEY里,保存第二天获取的是新的) String key = "SerialNum:" + redisKey.format(date) + "_" + serialNumberTypeEnum + "_" + orgId; // 设置过期类型(24 数量, TimeUnit 单位)此处需要与上面相对应 long serNum = getIncr(key, 24, TimeUnit.HOURS); // reids取序号从0开始,需要加1 serNum = serNum + 1; SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd"); final Long maxNum = 99999L; if (serNum > maxNum) { return sf.format(new Date()); } return sf.format(date) + StringUtils.leftPad(serNum + "", 5, "0"); } /** * 生成规则:生成规则:yyyMMdd00001 三位年+月+日+6位递增号 每天清零 * * @param orgId 机构ID * @param serialNumberTypeEnum 序列号类型 * @return 序列号 */ private String serMethod003(Long orgId, SerialNumberTypeEnum serialNumberTypeEnum) { Date date = new Date(); // 设置失效类型(yyyyMMdd为:每天失效,yyyyMM为:每月失效,yyyy为:每年失效,不要下段代码为:永久有效) SimpleDateFormat redisKey = new SimpleDateFormat("yyyyMMdd"); // redis上保存的KEY (将日期拼接到KEY里,保存第二天获取的是新的) String key = "SerialNum:" + redisKey.format(date) + "_" + serialNumberTypeEnum + "_" + orgId; // 设置过期类型(24 数量, TimeUnit 单位)此处需要与上面相对应 long serNum = getIncr(key, 24, TimeUnit.HOURS); // reids取序号从0开始,需要加1 serNum = serNum + 1; SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd"); final Long maxNum = 999999L; if (serNum > maxNum) { return sf.format(new Date()).substring(1); } return sf.format(date).substring(1) + StringUtils.leftPad(serNum + "", 6, "0"); } /** * 生成规则:9位递增号 不清零 * * @param orgId 机构ID * @param serialNumberTypeEnum 序列号类型 * @return 序列号 */ private String serMethod004(Long orgId, SerialNumberTypeEnum serialNumberTypeEnum) { // redis上保存的KEY (将日期拼接到KEY里,保存第二天获取的是新的) String key = "SerialNum:" + "_" + serialNumberTypeEnum + "_" + orgId; // 设置过期类型 不过期 long serNum = getIncr(key); // reids取序号从0开始,需要加1 serNum = serNum + 1; return StringUtils.leftPad(serNum + "", 9, "0"); } /** * 生成规则:省异地机构交易流水号-4位递增号 不清零 * * @param orgId 机构ID * @param serialNumberTypeEnum 序列号类型 * @return 序列号 30位 */ private String serMethod005(Long orgId, SerialNumberTypeEnum serialNumberTypeEnum) { Date date = new Date(); // 设置失效类型(yyyyMMdd为:每天失效,yyyyMM为:每月失效,yyyy为:每年失效,不要下段代码为:永久有效) SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss"); // redis上保存的KEY (将日期拼接到KEY里,保存第二天获取的是新的) String key = "SerialNum:" + "_" + serialNumberTypeEnum + "_" + orgId; // 设置过期类型(1 数量, TimeUnit 单位)此处需要与上面相对应 long serNum = getIncr(key, 1, TimeUnit.MINUTES) + 1; String newOrgId = String.valueOf(orgId); if (newOrgId.length() > 12) { newOrgId = newOrgId.substring(0, 12); } else { newOrgId = StringUtils.rightPad(newOrgId, 12, "0"); } return newOrgId + sf.format(date) + StringUtils.leftPad(serNum + "", 4, "0"); } /** * 获取指定key的值 * * @param keyType * @param obj * @param <T> * @return */ private <T> String getKeyTypeValue(String keyType, T obj) { try { Field field = obj.getClass().getDeclaredField(keyType); field.setAccessible(true); String type = (String)field.get(obj); return type; } catch (Exception e) { logger.error(e.getMessage(), e); } return null; } @Override /** * 获取当前的序列号 不自增 */ public Long getButNoIncr(String key) { key = "SerialNum:" + "_" + key ; return new RedisAtomicLong(key, redisTemplate.getConnectionFactory()).get(); } @Override /** * 按照给定的规则返回序列号值 * @param valueFunction 处理返回值的方法 * @param keyFunction 处理key值的方法 * @param days 保存有效期 单位是天 * @return */ public String getSerialNumber(Function<Long,String> valueFunction, Supplier<String> keyFunction, int days){ //SerialNumberTypeEnum serialNumberTypeEnum String key = "SerialNum:" + "_" + keyFunction.get() ; long serNum = getIncr(key,days,TimeUnit.DAYS); serNum = serNum + 1; return valueFunction.apply(serNum); } } ```