利用redis生成自定义code(编码)

原理:利用日期表达式生成时间字符串,利用redis的 increment 生成自增数字,保证code唯一。

具体格式如下:

如:CODE[D:yyyyMMdd][N:4]   生成结果:CODE202105200001
[]包裹的字符串是规则,在[]外的是固定字符串
[D:日期规则] :表示日期规则,获取日期。如:[D:yyyyMMdd] -> 20210520
[DL:日期规则] :表示日期规则,获取日期并转成字母。如:[DL:MMdd] -> 0520 -> 0EB0
[N:数值长度] :表示数值长度,获取N位数字。如:[N:4] -> 0001
[NL:数值长度] :表示数值长度,获取N位数字并转成字母。如:[N:4] -> 0001 -> 000A

代码如下:


import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 利用Redis的递增生成code
 *
 * @author zenan.qi
 * @date 2021-5-20
 */
@Component
public class CodeGenerator {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * @param rule code的生成规则 :如 CODE[D:yyyyMMdd][N:4]
     *             [D:日期规则] :表示日期规则,获取日期。如:[D:yyyyMMdd] -> 20210520
     *             [DL:日期规则] :表示日期规则,获取日期并转成字母。如:[DL:MMdd] -> 0520 -> 0EB0
     *             [N:数值长度] :表示数值长度,获取N位数字。如:[N:4] -> 0001
     *             [NL:数值长度] :表示数值长度,获取N位数字并转成字母。如:[N:4] -> 0001 -> 000A
     *             其余的为固定字符
     * @return code 如:CODE202105200001
     */
    public synchronized String nextCode(String rule) {
        String code = rule;
        Pattern pattern = Pattern.compile("\\[([A-Z]+):([^\\]]+)\\]");
        Matcher matcher = pattern.matcher(rule);
        while (matcher.find()) {
            String fullRule = matcher.group(0);
            String oneRule = matcher.group(1);
            String twoRule = matcher.group(2);
            String fullValue = "";
            //日期
            if (oneRule.startsWith("D")) {
                DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(twoRule);
                fullValue = dateTimeFormatter.format(LocalDateTime.now());
            }
            //数值
            if (oneRule.startsWith("N")) {
                System.out.println(code);
                ValueOperations<String, Object> ops = redisTemplate.opsForValue();
                ops.increment(code, 1L);
                Integer value = Integer.parseInt(ops.get(code).toString());

                fullValue = String.format("%0" + twoRule + "d", value);
            }
            if (StringUtils.contains(oneRule, "L")) {
                fullValue = numberTurnLetter(fullValue);
            }
            code = code.replace(fullRule, fullValue);
        }
        return code;
    }

    /**
     * 数字转字母,1-9 对应 A-I,0 对应 0
     *
     * @param s 数字字符串
     * @return 字母字符串
     */
    private String numberTurnLetter(String s) {
        String reString = "";
        for (int x = 0; x < s.length(); x++) {
            // 转换的单个字母
            String single = "";
            if (s.charAt(x) == '0') {
                single = "0";
            } else {
                char s1 = (char) (((s.charAt(x) - '0') - 1) + (int) 'a');
                String s2 = "" + s1;
                single = s2.toUpperCase();
            }
            reString = reString + single;
        }
        return reString;
    }
}

测试:

//YD固定字符串,4位年,2位月,2位日,4位自增长
System.out.println(codeGenerator.nextCode("YD[D:yyyyMMdd][N:4]"));
System.out.println(codeGenerator.nextCode("YD[D:yyyyMMdd][N:4]"));
//YD固定字符串,4位年,2位月字(字母显示),2位日(字母显示),4位自增长
System.out.println(codeGenerator.nextCode("YD[D:yyyy][DL:MMdd][N:4]"));
System.out.println(codeGenerator.nextCode("YD[D:yyyy][DL:MMdd][N:4]"));
//YD固定字符串,4位年,2位月字(字母显示),2位日(字母显示),4位自增长(字母显示)
System.out.println(codeGenerator.nextCode("YD[D:yyyy][DL:MMdd][NL:4]"));
System.out.println(codeGenerator.nextCode("YD[D:yyyy][DL:MMdd][NL:4]"));

结果

//YD固定字符串,4位年,2位月,2位日,4位自增长
YD202105210001
YD202105210002
//YD固定字符串,4位年,2位月字(字母显示),2位日(字母显示),4位自增长
YD20210EBA0001
YD20210EBA0002
//YD固定字符串,4位年,2位月字(字母显示),2位日(字母显示),4位自增长(字母显示)
YD20210EBA000A
YD20210EBA000B
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值