前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我写了一个简单通用的单号生成器

我写了一个简单通用的单号生成器

作者头像
Lvshen
发布2022-12-05 13:48:12
1.7K1
发布2022-12-05 13:48:12
举报

使用MySQL生成

相信大家在开发上都会遇到业务单号生成的需求,一般的生成格式为:

代码语言:javascript
复制
前缀 + YYMMDD + 序列号(例如3位序列号)

这里前缀 + 日期没有太大技术含量,主要是在尾部的序列号,这里要求3位序列号,我们从001开始。当等于10起,为010。当等于100起,为100。第二天重置从001起。这里我们可以使用MySQL数据库存储,这里我们需要记录日期和序号两个字段。MySQL 表如下:

代码语言:javascript
复制
CREATE TABLE `code_generator` (
  `id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `number` bigint(10) DEFAULT NULL COMMENT '序号',
  `gnerator_time` datetime DEFAULT NULL COMMENT '生成日期',
  `deleted` tinyint(1) DEFAULT '0' COMMENT '是否删除',
  `created_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建人',
  `created_time` datetime DEFAULT NULL COMMENT '创建时间',
  `updated_by` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '更新人',
  `updated_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='单号生成器'

调用生成方法时,判断当前日期与数据库生成日期gnerator_time是否为同一天。如果为同一天,在当天的数据下面 number + 1。如果不为同一天,删掉当前数据,插入一条number为1的数据。这里在计算number时注意添加锁,防止多线程下计算不准确。

使用Redis生成

当然,除了使用MySQL生成,还可以使用Redis来生成。相较于MySQL,Redis的性能更为优良。

这里我们使用Redisson API。

首先我们使用Spring注入一个Redisson客户端:

代码语言:javascript
复制
@Bean("redissonService")
public RedissonClient getRedissonClient() {

    String activeProfile = getActiveProfile();
    Config config;
    if ("prod".equals(activeProfile)) {
     config = useClusterConfig();
    } else {
     config = useSingleConfig();
    }
    return Redisson.create(config);
}

在配置RedissonClient时,可以设置为单机模式,或者集群模式。

这样就可以从容器中获取bean了。

代码语言:javascript
复制
@Autowired
private RedissonClientConfig redissonService;

生成编号的核心代码如下:

代码语言:javascript
复制
private synchronized long getSuffixCode(String key) {
    RedissonClient redissonClient = redissonService.getRedissonClient();
    RAtomicLong atomicVar = redissonClient.getAtomicLong(key);
    String todayStr = getTodayStr();
    String codeRecord = getCodeRecord(key);
    if (!atomicVar.isExists()) {
        atomicVar.set(1);
    }
    if (StringUtils.isNotBlank(codeRecord)) {
        if (!isSameDay(todayStr, codeRecord)) {
            atomicVar.set(1);
        }
    }
    saveCodeRecord(key, todayStr);
    long value = atomicVar.incrementAndGet();
    return value;
}

上面代码功能为生成序号。我们先在redis中查找,如果通过key能查到对应的值,则在这个值的基础上增加1。如果值不存在,设置为1。当然,如果当天日期与redis记录日期不是同一天,也需要将值置为1。

saveCodeRecord方法代码如下:

代码语言:javascript
复制
private void saveCodeRecord(String key, String value) {
    String recordKey = key + CODE_DATE_RECORD_KEY;
    redisUtils.set(recordKey, value);

序号如果小于10,则前面补两个个0。在10到100之间,补两个0。序号补位方法如下:

代码语言:javascript
复制
private String getSuffixCodeStr(String key, int digit) {
    long code = getSuffixCode(key);
    return getDigitNumber((int) code, digit);
}

public String getDigitNumber(int number, int digit) {
    NumberFormat formatter = NumberFormat.getNumberInstance();
    formatter.setMinimumIntegerDigits(digit);
    formatter.setGroupingUsed(false);
    return formatter.format(number);
}

之后我们再将前缀,日期,序号拼接起来即可:

代码语言:javascript
复制
private String generateCode(String prefix, String redisKey, int digit) {
    String dateStr = getTodayStr();

    String suffixCodeStr = getSuffixCodeStr(redisKey, digit);

    String[] codes = {prefix, dateStr, suffixCodeStr};
    return String.join("", codes);
}

我们再做一层简单的封装:

代码语言:javascript
复制
public String generatorCode(String prefix, int digit) {
    String redisKey = getRedisKey(prefix, "GENERAL_CODE");
    return generateCode(prefix, redisKey, digit);
}

generatorCode()说明如下:

❝生成的单号格式为:前缀 + YYMMDD + 序号 例如:generatorCode("D",4),当前日期为:2022-08-12 则生成单号:D202208120001 ❞

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Lvshen的技术小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用MySQL生成
  • 使用Redis生成
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档