一、准备工作
1、订单号数据存储在 Mysql 数据库中,需要安装 Mysql 数据库。
2、使用数据库存储过程生成编码和不使用存储过程在代码中生成编码,相同的是编码都是保存在数据库中。
二、程序实现
1、程序截图
2、实现思路
使用存储过程:在存储过程中进行查询和插入
不使用存储过程:在代码中先查询出来再进行插入
都是在数据库进行查询,然后插入
3、主要代码
存储过程如下:
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
入参为:
IN pre VARCHAR(32), IN preLen INT, IN num INT, IN noLen INT, OUT newCode VARCHAR(32)
不使用存储过程代码如下:
//代码同步,防止高并发
private final static ReentrantLock lock;
static{
lock = new ReentrantLock();
}
/**
* 不使用存储过程
*/
@Test
public void codeTest2(){
Map map = new HashMap();
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 类下的 两个测试方法
注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权