使用MySQL生成
相信大家在开发上都会遇到业务单号生成的需求,一般生成格式如下:
前缀 + YYMMDD + 序列号(如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
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至827202335@qq.com 举报,一经查实,本站将立刻删除。文章链接:https://www.eztwang.com/dongtai/76844.html