在项目中,新增某条记录的时候,为了定义某个不可重复的值,会采用自动生成流水号的方式来定义这个值。根据需要,定义的方法也多种多样,比如日期加3位流水号(例:20180115001)。因此了解到两种生成流水号的方法:
一、Java生成流水号
生成流水号格式为yyyyMMddXXXX
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class PrimaryGenerater {
private static final String SERIAL_NUMBER = "XXXX"; // 流水号格式
private static PrimaryGenerater primaryGenerater = null;
private PrimaryGenerater() {
}
/**
* 取得PrimaryGenerater的单例实现
*
* @return
*/
public static PrimaryGenerater getInstance() {
if (primaryGenerater == null) {
synchronized (PrimaryGenerater.class) {
if (primaryGenerater == null) {
primaryGenerater = new PrimaryGenerater();
}
}
}
return primaryGenerater;
}
/**
* 生成下一个编号
*/
public synchronized String generaterNextNumber(String sno) {
String id = null;
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
if (sno == null) {
id = formatter.format(date) + "0001";
} else {
int count = SERIAL_NUMBER.length();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
sb.append("0");
}
DecimalFormat df = new DecimalFormat("0000");
id = formatter.format(date)
+ df.format(1 + Integer.parseInt(sno.substring(8, 12)));
}
return id;
}
}
二、SQL生成流水号
同样以生成流水号格式为yyyyMMddXXXX为例
SELECT
IF (
max(a.st_no) IS NULL,
CONCAT(
date_format(now(),'%Y%m%d'),
LPAD('1', '11' - LENGTH(date_format(now(),'%Y%m%d'), '0')
),
CONCAT(
LEFT (max(a.st_no), 8),
LPAD(
CONVERT (
SUBSTRING(max(a.st_no), 9),
SIGNED
) + 1,
LENGTH(max(a.st_no)) - 8,
'0'
)
)
) AS st_no
FROM
Student a
WHERE
a.st_no LIKE concat(
date_format(now(),'%Y%m%d'),'%') AND LENGTH(a.st_no) = '11'
注意:
①示例中date_format(now(),'%Y%m%d')可以在后台业务逻辑层获取当前时间作为参数传入
②concat函数,拼接括号里的字符串 【例:调用concat("abc", "d", "ef", "g")函数返回abcdefg】
③lpad函数,用第三个参数填充到第一个参数的左边直到参数总长度达到第二个数值 【例:调用 lpad('sd',5,'*') 函数返回***sd】
④substring有三种用法【substring(‘abcdefg’,3)--->defg // substring('abcdefg',2,3) --->bcd // 'abcdefg'.substring(2,4) --->cd】
⑤此方法仅用于后三位小于等于999的数据,有一定的局限性