您的位置:闷文网 > 生活 > >正文

​录入单号自动生成序号(我写了一个简单的单号生成器)

摘要录入单号自动生成序号(我写了一个简单的单号生成器) 相信大家在开发上都会遇到业务单号生成的需求,一般的生成格式为:,我来为大家科普一下关于录入单号自动生成序号?下面...

录入单号自动生成序号(我写了一个简单的单号生成器)

相信大家在开发上都会遇到业务单号生成的需求,一般的生成格式为:,我来为大家科普一下关于录入单号自动生成序号?下面希望有你要的答案,我们一起来看看吧!

录入单号自动生成序号(我写了一个简单的单号生成器)

录入单号自动生成序号

使用MySQL生成

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

前缀   YYMMDD   序列号(例如3位序列号)

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

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客户端:

@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了。

@Autowired private RedissonClientConfig redissonService;

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

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方法代码如下:

private void saveCodeRecord(String key, String value) {     String recordKey = key   CODE_DATE_RECORD_KEY;     redisUtils.set(recordKey, value);

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

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); }

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

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); }

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

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

,

标签:

推荐阅读