ID编号生成
ID编号生成
主要功能
- 分布式ID生成:使用cosid库进行分布式ID的生成
- 自定义code生成
引入依赖
implementation("team.aikero.blade:blade-sequence-spring-boot-starter:${latestVersion}")<dependency>
<groupId>team.aikero.blade</groupId>
<artifactId>blade-sequence-spring-boot-starter</artifactId>
<version>${latestVersion}</version>
</dependency>ID生成
配置
通常默认的配置项已经满足需要,如果需要修改,可以在nacos中进行修改,也可以在自己项目中进行修改。 默认的配置如下:
# 与cosid的配置后续考虑统一前缀
blade:
sequence:
#集成mp的id生成器
mybatis-plus:
generator-name: __share__
# Code编号生成器类型
code:
belong: qinkangdeid
namespaces: ${spring.application.name}
# sequence包装cosid 所以需要cosid配置
cosid:
namespace: ${spring.application.name}
snowflake:
enabled: true
epoch: 1654016400
machine:
enabled: true
distributor:
type: redis
guarder:
enabled: true使用
原则上这一版服务内部的ID生成使用方式都是不变,但为了使用可以更加简便,可以一起改变一下使用方式,针对的使用方式为:
- 方式一:手动获取
- 方式二:MP注解自动填充
- 方式三:Jimmer注解自动填充
- 方式四:想要高自定义选择
方式一: 手动获取
// 手动设置ID
val id = IdHelper.id手动获取ID的方式仅在需要进行多表插入做关联时使用,例如:当A表的ID需要在B表内做关联,或者在一个逻辑内需要同时插入A表和B表的情况下,可以预先获取ID。
方式二:MP注解自动填充
自定义MPID生成器(IdentifierGenerator)并且设置ID生成规则为IdType.ASSIGN_ID,例如
@TableId(value = "table_id", type = IdType.ASSIGN_ID)
var tableId:Long?=null我们自定义了MP的ID生成器CosidIdMybatisPlusIdentifierGenerator并实现了自动初始化,使其开箱即用。
Cosid支持多种ID生成器的声明和使用,默认情况下我们使用它的默认__share__生成器作为我们的默认ID填充器。如果想要使用自定义生成器,可以通过配置 cosid.snowflake.mp-generator来指定生成器名称。
方式三:Jimmer注解获取
方式四:Cosid注解自动
通过使用@CosId注解,可以配置CosId注解的设置项,通常情况下可以静默使用,如果需要进行具体设置,请查看注解内容。其他方式则按照cosid的说明进行使用即可。
@CosId
var tableId:Long?=null注意事项
对于使用mybatisPlus的情况下: 无论采用何种方式,我们都不应该选择使用MySQL自增主键生成策略。数据库实体类应该设置策略为IdType.ASSIGN_ID。从IdType枚举类中摘取内容,并查看斌哥的注释,可以得知ASSIGN_ID是兼顾INPUT类型的最妥当策略。
@Getter
public enum IdType {
/* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
/**
* 用户输入ID
* <p>该类型可以通过自己注册自动填充插件进行填充</p>
*/
INPUT(2),
/**
* 分配ID (主键类型为number或string),
* 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(雪花算法)
*
* @since 3.3.0
*/
ASSIGN_ID(3),
}业务编码生成器
我们提供了两种业务编码生成器的方式:
普通方式:类似于 xx单号,格式为(后两位)年(两位)月(两位)日+4位流水号,生成例如 F2303010001 的编码。
随机数方式:类似于 CRY2311300123456789,其中包含全部随机的数字和字母。
我们内置了这两种编码的默认实现,通常可以满足一般的业务场景。如果不满足需求,也可以自定义实现。
配置项
# Code编号生成器类型
blade:
sequence:
code:
enabled: true # 需要显式声明
belong: qinkangdeid # 默认为fashion
namespaces: ${spring.application.name}使用
使用内置方式:
// 普通模式
val rule = DefaultSimpleCodeRule(
code = "KH",
key = "CUSTOMER_CODE",
datePrefix = "yy",
incrRule = "%1\$05d",
desc = "客户编码"
)
val code = this.businessCodeGenerator.generate(rule)
// 随机模式
val rule = DefaultRandomCodeRule(
code = "CRY",
key = "DEMAND_CODE",
datePrefix = "YYMMdd",
incrRule = "0123456789",
desc = "需求编码",
)
val code = this.businessCodeGenerator.generate(rule)自定义枚举方式
enum class DemoCodeRuleEnum(
/**
* 代码
*/
override val code: String,
/**
* redis key
*/
override val key: String,
/**
* 日期的前缀
*/
override val datePrefix: String = "",
/**
* 增加规则
*/
override val incrRule: String = "",
/**
* desc
*/
override val desc: String = ""
) : SimpleCodeRule {
/**
* xx单号: (后两位)年(两位)月(两位)日+4位流水号 => F2303010001
*/
PROCESS_CODE("F", "PROCESS_CODE", "yyMMdd", "%1$04d", "xx单号"),
PROCESS_CODE2("F", "PROCESS_CODE222", "yyMMdd", "%1$04d", "yyy单号"),
;
}自定义使用
// businessCodeGenerator 为自动注入的业务编码生成器
businessCodeGenerator.generate(DemoCodeRuleEnum.PROCESS_CODE)定义普通类
?>TODO 待完善
注意事项
如果涉及到跨服务共用的key,由于redisKey默认添加了服务名为前序,需要手动添加
blade.sequence.code.namespaces配置。对于旧服务改造为blade,需要重写namespaces()方法以覆盖默认行为,以防止生成的code重复。
