批次号/订单号生成
概述
在系统内部或与其他系统进行对接对编码有一定自定义规则,包括批次号、订单号,比如 PCH20170727152245000001 编码规范 = 开头字母 + 年月日时分秒 + 序号 ,使用存储过程和不使用存储过程两种方式,数据都是存在 mysql 数据库中。
详细
一、准备工作
1、订单号数据存储在 Mysql 数据库中,需要安装 Mysql 数据库。
2、使用数据库存储过程生成编码和不使用存储过程在代码中生成编码,相同的是编码都是保存在数据库中。
二、程序实现
1、程序截图
2、实现思路
使用存储过程:在存储过程中进行查询和插入
不使用存储过程:在代码中先查询出来再进行插入
都是在数据库进行查询,然后插入
3、主要代码
存储过程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | BEGIN -- 当前日期 DECLARE currentDate VARCHAR (15); -- 离现在最近的满足条件的编码 DECLARE oldCode VARCHAR (25) DEFAULT '' ; -- oldCode的流水号 DECLARE maxNo INT DEFAULT 0; IF num = 4 THEN -- yyyy SELECT DATE_FORMAT(NOW(), '%Y' ) INTO currentDate; ELSEIF num = 6 THEN -- yyyymm SELECT DATE_FORMAT(NOW(), '%Y%m' ) INTO currentDate; ELSEIF num = 8 THEN -- yyyymmdd SELECT DATE_FORMAT(NOW(), '%Y%m%d' ) INTO currentDate; ELSEIF num = 12 THEN -- yyyymmddHHii SELECT DATE_FORMAT(NOW(), '%Y%m%d%H%i' ) INTO currentDate; ELSEIF num = 14 THEN -- yyyymmddHHiiss SELECT DATE_FORMAT(NOW(), '%Y%m%d%H%i%s' ) INTO currentDate; END IF; -- 显示最后一条数据 SELECT IFNULL(code, '' ) INTO oldCode FROM code_test WHERE SUBSTRING(code,1,preLen) = pre AND SUBSTRING(code,(preLen + 1),num) = currentDate AND LENGTH(code) = preLen + num + noLen ORDER BY id DESC LIMIT 1; -- 编码不为 '' 截取编码的最后noLen位 IF oldCode != '' THEN SET maxNo = CONVERT( SUBSTRING(oldCode, - noLen), DECIMAL ); END IF; -- 如果流水号不足noLen位,用0填充左边 SELECT CONCAT( pre, currentDate, LPAD((maxNo + 1), noLen, '0' ) ) INTO newCode; -- 插入数据 INSERT INTO code_test (code) VALUES (newCode); SELECT newCode; END |
入参为:
1 | IN pre VARCHAR(32), IN preLen INT, IN num INT, IN noLen INT, OUT newCode VARCHAR(32) |
不使用存储过程代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | //代码同步,防止高并发 private final static ReentrantLock lock; static { lock = new ReentrantLock(); } /** * 不使用存储过程 */ @Test public void codeTest2(){ Map<String, Object> map = new HashMap<String, Object>(); String pre = "PCH" ; Integer preLen = 3 ; Integer num = 4 ; Integer noLen = 4 ; Date curr = new Date(); SimpleDateFormat formatter = null ; switch (num) { case 4 : formatter = new SimpleDateFormat( "yyyy" ); break ; case 6 : formatter = new SimpleDateFormat( "yyyyMM" ); break ; case 8 : formatter = new SimpleDateFormat( "yyyyMMdd" ); break ; case 12 : formatter = new SimpleDateFormat( "yyyyMMddHHmm" ); break ; case 14 : formatter = new SimpleDateFormat( "yyyyMMddHHmmss" ); break ; default : break ; } String currentDate = formatter.format(curr); map.put( "pre" , pre); map.put( "preLen" , preLen); map.put( "num" , num); map.put( "noLen" , noLen); map.put( "currentDate" , currentDate); lock.lock(); String newCode = "" ; String newNo = "" ; try { String oldCode = codeTestDao.getOldCode(map); if (StringUtils.isEmpty(oldCode)) { newNo = "1" ; } else { Integer maxNo = Integer.parseInt(oldCode.substring(oldCode.length() - noLen)); newNo = String.valueOf(maxNo + 1 ); } int length = newNo.length(); if (length > noLen){ System.out.println( "新流水号位数超限" ); } for ( int i = 0 ; i < noLen - length; i++) { newNo = "0" .concat(newNo); } newCode = pre + currentDate + newNo; CodeTest codeTest = new CodeTest(); codeTest.setCode(newCode); codeTestDao.saveSelective(codeTest); } finally { lock.unlock(); } System.out.println( "生成的编码为:" +newCode); } |
三、运行效果
1、将 db 文件夹下的 test.sql 导入数据库
2、修改 jdbc.properties 文件中 mysql 连接
3、执行 CodeJunitTest 类下的 两个测试方法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?