日期流水号
年月日+六位数流水号,每天序号都从 000 001 开始,例如:20210322000001
定义一个生成流水号的方法generateNo(date)
,在需要获取流水号的地方调用该方法,方法入参是当前系统时间,使用的LocalDate
日期时间类
/**
*
*获取当前日期时间的流水号
*/
@Override
public String generateNo(LocalDate date) {
String dateStr = date.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
//从数据库获取当前日期流水号
String nextNo = this.getBaseMapper().getNextNo(dateStr);
//存在直接返回,不存在返回 dateStr + "000001"
if (nextNo == null) {
return dateStr + "000001";
}
return nextNo;
}
执行的sql
<select id="getNextNo" resultType="java.lang.String">
select MAX(CAST(no AS INTEGER)) + 1 as next_no
from cha_change_mst
where no like CONCAT(#{dateStr}, '%');
</select>
根据传入的日期时间模糊查询,查出最大值 + 1, 如果今天没有流水号会返回 null
MAX(
字段名)
:获取该字段最大值
CAST(
字段名AS
数据类型)
: 转换数据类型,因为这里 no 字段类型是varchar,需要换成 integer 类型做加法
单身流水(单笔)
向已存在的订单中新增单笔单身时,在现有的最大单身编号上加1
/**
* 依照单头取得单身最大流水号
* @param masterUuid 单头uuid
* @return
*/
@Override
public String generateNo(String masterUuid) {
String nextNo = this.getBaseMapper().getNextNo(masterUuid);
if (nextNo == null) {
nextNo = "1";
}
return StringUtils.leftPad(nextNo, 3, "0"); // 3位数, 不足位数前面补 0, ex: 001,002,003
}
执行的sql
<select id="getNextNo" resultType="java.lang.String">
select MAX(CAST(no AS INTEGER)) + 1 as next_no
from cbi_base_cust_addr
where cbi_base_cust_uuid = #{masterUuid}
</select>
单身流水(多笔)
同时新增订单单头和多笔单身时,单身单号连续不断号,通过简单的 for 循环和 StringUtils.leftPad
补足前缀即可
int i = 1; // 主要, 流程从1 开始
for (OrderDetailCreateDto detailDto : detailDtos) {
OrderDetail detail = new OrderDetail();
StringUtils.leftPad(Integer.toString(i++), 2, "0") // 2位数, 不足位数前面补 0, ex: 01,02,03
detail.setNo();
details.add(detail);
}
单表流水
单表不重复,10位数,序号都是从1开始升序,不足位补0,例如:0000000001
@Override
public String generateNo() {
String nextNo = this.getBaseMapper().getNextNo();
if (nextNo == null) {
nextNo = "1";
}
return StringUtils.leftPad(nextNo, 10, "0");// 10位数, 不足位数前面补 0, ex: 0000000001,0000000002,0000000003
}
执行的sql
<select id="getNextNo" resultType="java.lang.String">
select MAX(CAST(no AS INTEGER)) + 1 as next_no
from cbi_base_cust
</select>