运用redis实现自定义日期生成id

使用方式:
//生成任务编码
String key = “applicationCode”+ LocalDate.now().format(DateTimeFormatter.ofPattern(“yyyyMMdd”));
String applicationCode = idTimeUtils.getDayIncrCode(“”,key,4);

import cn.hutool.core.util.StrUtil;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;

import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;

/**
 * @author 
 * @version 1.0
 * @date 2021/10/9 16:17
 *
 * @desc    本工具类:用于生成(默认日期yyyyMMdd + 自定义位数)自增id
 *          自增顺序有效期仅为当日,隔天清理
 */
@Service
public class IdTimeUtils {


    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    CacheService cacheService;

    /**
     * redis key的层级不能超过3层()
     * 根据前缀+日期+每天的自增编号例如(WF2021041411200001)
     *
     * 使用方式    idTimeUtils.getDayIncrCode("SC", key, 5);  表示前缀SC,key 表示存在redis中的key,  5表示5位数
     *            例如:  地区编号+日期+5为  可getDayIncrCode(010210,key随意建议直接存当天日期, 5)即可
     *
     * @param prefix  前缀,可以是地区编码组合 ,或任意字母
     * @param key     表示存在redis中的key ,建议直接存当天日期加特殊符号前缀等
     * @param length  表示自增位数位数
     * @return  例如SC2021100900181    SC 20211009 00181
     */
    public String getDayIncrCode(String prefix, String key, int length) {
        String code = "";
        String formatDay = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        Long dayEndTime = getAppointDateTimeMills();
        //当天失效, 再加上300秒过期时间 防止凌晨系统时间不统一造成误差问题
        long liveTime = (dayEndTime - System.currentTimeMillis()) / 1000 +300;
        Long incre = getIncre(key, liveTime);
        String sequence = getSequence(incre, length);
        if (StrUtil.isNotBlank(prefix)) {
            code = code + prefix;
        }
        code = code + formatDay + sequence;

        return code;
    }

    public String getAttachmentName(String prefix, String key, int length) {
        String code = "";
        String formatDay = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        Long dayEndTime = getAppointDateTimeMills();
        //当天失效, 再加上300秒过期时间 防止凌晨系统时间不统一造成误差问题
        long liveTime = (dayEndTime - System.currentTimeMillis()) / 1000 +300;
        Long incre = getIncre(key, liveTime);
        String sequence = getSequence(incre, length);
        code = code + formatDay +prefix+sequence;

        return code;
    }

    /**
     * 获取指定时间毫秒值
     *
     * @return
     */
    public static Long getAppointDateTimeMills() {
        Calendar ca = Calendar.getInstance();
        //失效的时间
        ca.set(Calendar.HOUR_OF_DAY, 23);
        ca.set(Calendar.MINUTE, 59);
        ca.set(Calendar.SECOND, 59);
        long curtime = ca.getTimeInMillis();
        return curtime;
    }

    /**
     * 获取redis原子自增数据
     *
     * @param key
     * @param liveTime
     * @return
     */
    public Long getIncre(String key, long liveTime) {
        RedisAtomicLong counter = null;
        RLock lock = cacheService.getRLock(key);
        if (!redisTemplate.hasKey(key)) {
            try {
                lock.lock(5,TimeUnit.SECONDS);
                counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
            } finally {
                lock.unlock();
            }
        } else {
            counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        }
        Long increment = counter.incrementAndGet();
        //初始设置过期时间
        boolean result = (null == increment || increment.longValue() == 0) && liveTime > 0;
        if (result) {
            counter.set(1);
            counter.expire(liveTime, TimeUnit.SECONDS);
            increment = 1L;
        }
        // 先增后拿,所以第一次为1时设置下过期时间
        if (increment.longValue() == 1) counter.expire(liveTime, TimeUnit.SECONDS);
        return increment;
    }

    /**
     * 补全自增的数据
     *
     * @param seq
     * @param length
     * @return
     */
    public static String getSequence(long seq, int length) {
        String str = String.valueOf(seq);
        int len = str.length();
        // 取决于业务规模,应该不会到达4
        if (len >= length) {
            return str;
        }
        int rest = length - len;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < rest; i++) {
            sb.append('0');
        }
        sb.append(str);
        return sb.toString();
    }
}

CacheService


/**
 * The type Redis service.
 * 缓存服务
 */
@Component
public class CacheService implements InitializingBean, DisposableBean {
    private static Logger logger = LoggerFactory.getLogger(CacheService.class);

    // 缓存超时时间,单位:秒 ,默认1天
    private int defaultExpireTime = 60 * 60 * 24;

    @Resource
    private RedisConfig redisConfig;

    private RedissonClient redissonClient;

    @Override
    public void afterPropertiesSet() throws Exception {
        redissonClient = redisConfig.createRedissonClient();
    }

    public void setWithSecondsTime(String key, int expireTime, Object value) {
        this.getRBucket(redissonClient, key).set(value, expireTime, TimeUnit.SECONDS);
    }

    public void setAsync(String key, int expireTime, Object value) {
        this.getRBucket(redissonClient, key).setAsync(value, expireTime, TimeUnit.SECONDS);
    }

    public void setForever(String key, Object value) {
        this.getRBucket(redissonClient, key).set(value);
    }

    public void setWithSecondsTime(String key, Object value) {
        this.getRBucket(redissonClient, key).set(value, defaultExpireTime, TimeUnit.SECONDS);
    }

    public void setExpireAtTime(String key, Object value, Date expireAtTime) {
        RBucket<Object> rBucket = this.getRBucket(redissonClient, key);
        rBucket.set(value);
        rBucket.expireAt(expireAtTime);
    }

    public void setAsync(String key, Object value) {
        this.getRBucket(redissonClient, key).setAsync(value, defaultExpireTime, TimeUnit.SECONDS);
    }

    public boolean isExists(String key) {
        RKeys keys = redissonClient.getKeys();
        long count = keys.countExists(key);
        return count > 0;
    }

    public Object get(String key) {
        return this.getRBucket(redissonClient, key).get();
    }

    public String getStringValue(String key) {
        if (ObjectUtil.isNullObj(this.getRBucket(redissonClient, key).get())) {
            return null;
        }
        return (String) this.getRBucket(redissonClient, key).get();
    }

    public void delete(String key) {
        this.getRBucket(redissonClient, key).delete();
    }

    private <T> RBucket<T> getRBucket(RedissonClient redisson, String objectName) {
        return redisson.getBucket(objectName);
    }

    public RLock getRLock(String objectName) {
        return redissonClient.getLock(objectName);
    }

    public RAtomicLong getRAtomicLong(String objectName) {
        return redissonClient.getAtomicLong(objectName);
    }

    public RScheduledExecutorService getScheduledTask(String key) {
        return redissonClient.getExecutorService(key);
    }

    public void deletePrefix(String prefix) {
        RKeys keys = redissonClient.getKeys();
        keys.deleteByPattern(prefix + '*');
    }

    @Override
    public void destroy() throws Exception {
        redissonClient.shutdown();
        logger.info("CacheService destroy redissonClient!");
    }

    public <K, V> RMap<K, V> getMap(String key) {
        return redissonClient.getMap(key);
    }

    public <T> RList<T> getList(String key, Codec codec) {
        return redissonClient.getList(key, codec);
    }

    public <T> RList<T> getList(String key) {
        return redissonClient.getList(key);
    }


    public <T> RSortedSet<T> getSoredSet(String key) {
        return redissonClient.getSortedSet(key);
    }

    public RBlockingQueue<Object> getRQueue(String key) {
        return redissonClient.getBlockingQueue(key);
    }

    public void setExpireAtTime(String key, Object value, long expireTime, TimeUnit timeUnit) {
        RBucket<Object> rBucket = this.getRBucket(redissonClient, key);
        rBucket.set(value);
        rBucket.expire(expireTime, timeUnit);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用spring-session-data-redis时,可以自定义sessionId生成策略。默认情况下,sessionId是使用java.util.UUID生成的随机字符串。要自定义sessionId,需要创建一个实现了`org.springframework.session.web.http.SessionIdResolver`接口的类,并将其配置为Spring Session的bean。 例如,可以创建一个自定义的sessionId生成器,该生成器在每个会话中使用客户端提供的自定义标头作为sessionId。该实现类可以如下所示: ```java import javax.servlet.http.HttpServletRequest; import org.springframework.session.web.http.HttpSessionIdResolver; public class CustomSessionIdResolver implements HttpSessionIdResolver { private static final String HEADER_NAME = "Custom-Session-Id"; @Override public List<String> resolveSessionIds(HttpServletRequest request) { String sessionId = request.getHeader(HEADER_NAME); if (sessionId != null) { return Collections.singletonList(sessionId); } else { return Collections.emptyList(); } } @Override public void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) { response.setHeader(HEADER_NAME, sessionId); } @Override public void expireSession(HttpServletRequest request, HttpServletResponse response) { response.setHeader(HEADER_NAME, ""); } } ``` 然后,可以在Spring配置中将`CustomSessionIdResolver`类注册为Spring Session的bean,例如: ```java @Configuration @EnableRedisHttpSession public class RedisHttpSessionConfig { @Bean public HttpSessionIdResolver httpSessionIdResolver() { return new CustomSessionIdResolver(); } } ``` 这样,每次请求到来时,Spring Session就会使用自定义的sessionId解析器生成或者获取sessionId
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值