批次号/订单号生成

概述

在系统内部或与其他系统进行对接对编码有一定自定义规则,包括批次号、订单号,比如 PCH20170727152245000001 编码规范 = 开头字母 + 年月日时分秒 + 序号 ,使用存储过程和不使用存储过程两种方式,数据都是存在 mysql 数据库中。

详细

 

更多个人文章请点击

一、准备工作

1、订单号数据存储在 Mysql 数据库中,需要安装 Mysql 数据库。

2、使用数据库存储过程生成编码和不使用存储过程在代码中生成编码,相同的是编码都是保存在数据库中。

二、程序实现

1、程序截图

1501347344494015101.png

 

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 类下的 两个测试方法

1501347916264090866.png

 

 

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

posted on   demo例子集  阅读(3180)  评论(0编辑  收藏  举报

(评论功能已被禁用)
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示