使用以下技术栈
- springboot
- mybatisplus
- mysql
一、首先设计一张表
表名假设为auto_numbering
名称 | 数据类型 | 备注 | 描述 |
---|---|---|---|
id | bigint | 主键 | |
name | varchar(64) | 编号名称 | |
prefix | varchar(8) | 前缀 | |
inti_value | bigint | 初始值 | |
current_value | bigint | 当前值 | |
length | int | 编号长度(不包含前缀) |
假设有两条数据
id | name | prefix | inti_value | current_value | length |
---|---|---|---|---|---|
1 | stock_input | SI | 0 | 2 | 8 |
2 | product_code | PC | 0 | 5 | 8 |
第一条表示入库单编号,编号的规则是,前缀为SI,当前编号数为2,长度为8,那么下一次使用入库单号时,对应的current_value加1变为3,得到的单号应该是字符串"SI00000003"
。第二条表示产品编号,同理,对应的current_value加1变为6,应该得到字符串"PC00000006"
。
那么如何设计这样一个自动编号工具类呢?这个工具类的方法最好是static
,这样可以直接得到自动编号器的返回值,同时又要去让数据表对应的current_value
自增。
二、创建对应的Domain类、Mapper接口、编号名称枚举类
domain
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("auto_numbering")
public class AutoNumbering{
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 编号名称
*/
private String name;
/**
* 前缀
*/
private String prefix;
/**
* 初始值
*/
private Long intiValue;
/**
* 当前值
*/
private Long currentValue;
/**
* 编号长度(不包含前缀)
*/
private Integer length;
}
mapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AutoNumberingMapper extends BaseMapper<AutoNumbering> {
}
enum
public enum AutoNumberingEnum {
STOCK_INPUT("stock_input", "入库编号"),
PRODUCT_CODE("product_code", "产品编号");
private final String name;
private final String remark;
AutoNumberingEnum(String name, String remark) {
this.name = name;
this.remark = remark;
}
/**
* 获取枚举名称
*
* @return name
*/
public String getName() {
return this.name;
}
/**
* 获取枚举描述
*
* @return remark
*/
public String getRemark() {
return this.remark;
}
}
三、写一个Service接口和实现类
service接口类
public interface AutoNumberingService {
/**
* 获取下一个编号
* @param param 自动编号枚举值
* @return 自动编号字符串
*/
String getNextNo(AutoNumberingEnum param);
}
serviceimpl
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
public class AutoNumberingServiceImpl implements AutoNumberingService {
@Autowired
private AutoNumberingMapper autoNumberingMapper ;
/**
* 自动编号方法
*
* @param param 自动编号枚举值
* @return 编号
*/
@Transactional
public String getNextNo(AutoNumberingEnum param) {
// 查找当前的采番配置信息
LambdaQueryWrapper<AutoNumbering> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(AutoNumbering::getName, param.getName());
List<AutoNumbering> AutoNumberings = AutoNumberingMapper.selectList(wrapper);
// 未获取到配置信息
if (AutoNumberings.isEmpty()) {
return null;
} else {
// 规则获取
AutoNumbering autoNumbering = AutoNumberings.get(0);
// 前缀
String prefix = autoNumbering.getPrefix();
// 长度
Integer length = autoNumbering.getLength();
// 顺番
Long currentNo = autoNumbering.getCurrentValue();
// 更新原数据
currentNo++;
}
autoNumbering.setCurrentValue(currentNo);
AutoNumberingMapper.updateById(autoNumbering);
// 生成编号
String formatNo = StringUtils.leftPad(String.valueOf(currentNo), length, "0");
return String.format("%s%s", prefix, formatNo);
}
}
四、写一个Utils类静态获取编号
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class NoGeneratorUtil {
private static AutoNumberingService autoNumberingService;
@Autowired
public void setAutoNumberingService(AutoNumberingService autoNumberingService) {
NoGeneratorUtil.autoNumberingService = autoNumberingService;
}
/**
* 获取最新的入库单编号
* @return 最新的入库单编号
*/
public static String getNextStockInputNo() {
return autoNumberingService.getNextNo(AutoNumberingEnum.STOCK_INPUT);
}
/**
* 获取最新的产品编号
* @return 最新的c'p 编号
*/
public static String getNextProductNo() {
return autoNumberingService.getNextNo(AutoNumberingEnum.PRODUCT_CODE);
}
这段代码是SpringBoot
框架中的一种常见用法,用于将SpringBoot
管理的bean
注入到静态变量中。那么,autoNumberingService
是如何被注入的呢?实际上,当SpringBoot
启动时,它会扫描所有的类,并为带有@Component
(或者@Service
等)注解的类创建实例。在创建NoGeneratorUtil
实例的过程中,SpringBoot
会调用所有带有@Autowired
注解的setter
方法,包括setAutoNumberingService
方法,从而将AutoNumberingService
的实现类注入到autoNumberingService
静态变量中。
五、使用
之后如下使用即可一行代码获取最新编号
String string1 = NoGeneratorUtil.getNextStockInputNo();
String string2 = NoGeneratorUtil.getNextProductNo();