使用以下技术栈
- 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
language-java1 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
| 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
language-java1 2 3 4 5 6 7 8 9
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper;
@Mapper public interface AutoNumberingMapper extends BaseMapper<AutoNumbering> {
}
|
enum
language-java1 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
| 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接口类
language-java1 2 3 4 5 6 7 8 9 10
| public interface AutoNumberingService {
/** * 获取下一个编号 * @param param 自动编号枚举值 * @return 自动编号字符串 */ String getNextNo(AutoNumberingEnum param); }
|
serviceimpl
language-java1 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
| 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类静态获取编号
language-java1 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
| 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
静态变量中。
五、使用
之后如下使用即可一行代码获取最新编号
language-java1 2
| String string1 = NoGeneratorUtil.getNextStockInputNo(); String string2 = NoGeneratorUtil.getNextProductNo();
|