# simple-number **Repository Path**: natural-meow/simple-number ## Basic Information - **Project Name**: simple-number - **Description**: 一个编号生成工具,可以快速集成到项目中,实现 前缀 + 年 + 序号 例如:XD202109030001 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2025-07-16 - **Last Updated**: 2025-07-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 初衷 在项目中偶尔会使用临时的一个编号规则,为了不重复造轮子,进行了封装,来解决日常项目中使用一些简单编号的场景 ## 实现方案 1、使用**redis**作为存储序号,而生成编号 2、使用**mysql**作为存储序号,而生成编号 ## 方案优点以及功能说明: 优点: 1. 全局唯一、基于Redis性能高 2. 支持根据业务特性生成,如有序自增、可配置是否需要业务模块前缀、定制日期格式、是否需要按天重置、定制生成的序列ID位数自动补位等 3. 支持Redis多数据源,可通过独立部署Redis服务器的方式隔离Redis业务数据,避免ID序列被清空失效,可通过Redis集群解决单点故障问题,实现高可用。 4. 内置服务降级策略, 也支持自定义降价策略,当Redis生成ID服务不可用时,会采取服务降级策略生成。 5. 基于Lua脚本实现Next Id获取不会出现并发问题。 6. 基于spring-boot-starter方式封装,接入方便。 > **可根据规则自定义生成ID效果展示:** > > 数字递增,自定义补位不足补0:00001、00002、00003...00100、00101 > > 模块标识+数字递增:XD0001、XD0002... > > 模块标识+日期格式(可精确到秒)+数字递增:XD202109030001、XD202109030002.... > > 日期格式+数字递增:202109030001、202109030002... > > 日期按天重置序列:202109030001、202109030002...202109040001、202109040002... > > 自定义序列递增步长,每自增一个加5:202109030005、202109030010... > > 更多规则,支持自定义灵活配置。 ### 1、number组件的配置 ```yaml number: mysql: app-name: name # 用于区分id的服务,达到不同服务不同的id,不配置默认获取spring.application.name enable: true #是否启用MysqlID,默认false,非必填 datasource: url: jdbc:mysql://101.43.47.221:3306/lyj_use?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT username: root password: 123456 redis: app-name: name # 用于区分id的服务,达到不同服务不同的id,不配置默认获取spring.application.name enable: true #是否启用RedisID,默认false,非必填 host: 127.0.0.1 #redis id生成服务的redis服务器配置信息,非必填,不配置时取spring.redis.host port: 6379 #非必填,不配置时取spring.redis.port password: #非必填,不配置时取spring.redis.password database: 1 #非必填,默认为0,建议配置与项目应用使用的database配置不同的database区别开来进行隔离 timeout: 6000 # 连接超时时长(毫秒),非必填 lettuce: #非必填 commandTimeout: 1 #秒s ,非必填 shutdownTimeout: 100 #毫秒ms,非必填 pool: max-active: 32 # 连接池最大连接数(使用负值表示没有限制),非必填 max-wait: 300 # 连接池最大阻塞等待时间(使用负值表示没有限制),非必填 max-idle: 16 # 连接池中的最大空闲连接,非必填 min-idle: 8 # 连接池中的最小空闲连接,非必填 # 目前还不支持集群的配置 # cluster: #集群配置信息,该节点可不配置,留待后续redis扩展集群使用,目前只有单机,非必填 # max-redirects: 3 # 获取失败 最大重定向次数,非必填 # timeout: 1000 #,非必填 # #nodes: 127.0.0.1:6379 #非必填,配置时将使用redis集群,不配置则使用上面配置的redis单机 ``` > 上述配置说明: > > 1、整体配置分为两部分:a.若需要使用mysql number.mysql部分,b.若需要redis则配置number.redis部分,只有开启enable = true 才可以使用对应的服务,可以同时开启 > > 2、关于为什么弄了个跟spring.redis一样的配置,多次一举?:考虑到我们有时会直接去将Redis上面的缓存清空,而使用Redis会对序列进行递增,会生成一些key,而这些key是不能删除的,否则会导致序列重置出问题,所以为了避免风险,做了Redis多数据源,将使用的redis与应用本身使用的redis进行隔离,可以使用不同的Redis服务器,你可以是多个项目都用同一个Redis服务器来专门给Number使用,而应用使用另外的redis服务器。当然如果嫌麻烦也可以与项目本身使用同一个redis服务器,可配置不同的database隔离。 > mysql 是同理 > 3、**使用mysql时,一定要先在项目数据库中使用generate_serialnum.sql 脚本先创建分配节点的数据库表。** > > 4、其余的配置可参考:https://gitee.com/blind/bid-spring-boot-starter/blob/master/README.md > > ## 快速开始 > 接下来就快速开始吧! > 这个例子可以帮你快速引入Number 生成序号,更多的自定义需要仔细阅读配置 > ### 1、目前没有推到maven仓库 需要自己打包上传到自己公司maven ### 2、在需要的工程中引入组件依赖 > ``` > > com.ninth.element > ninth-element-generated-number > 1.0-SNAPSHOT > > > * > org.mybatis > > > * > mysql > > > > > UID需要依赖mysql数据库、mybatis,若项目已有这些依赖请将其排除掉,其他数据库如Oracle未测试过。 > ``` > ### 3、配置文件中启用对应的服务 redis ```yaml number: redis: enable: true ``` mysql 如果使用到mysql请先去执行sql/generate_serialnum.sql创建对应的表 ```yaml number: mysql: enable: true datasource: url: jdbc:mysql://localhost:3306/name?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT username: root password: root ``` ### 4、创建配置类将生成编号的模板注入到 factory redis ```java @Configuration public class NumberConfig { @Bean(name = "fullRedisIdTemplate") public RedisIdTemplate fullRedisIdTemplate() { RedisIdPatternConfiguration redisIdConfig = RedisIdPatternConfiguration.builder() //redis的key名称,同时也是ID前缀(如果需要拼接前缀的话) -- 必须配置 .key("DEMO12") //日期格式,不传默认不拼接日期 --- 选配 .dateTimeFormatter(SimpleDateFormatter.FORMATTER_DAY) //生成ID的位数,如果不配置默认补位,如配置5,此时Redis序列值为“6”小于5位数,则生成的ID为00006 --- 选配 .digits(6) //递增步长,如当前序列值为5,配置increment=5则下次序列为10 --- 选配 .increment(1) //序列初始值,不配置不覆盖redis的值,若配置值小于redis服务器序列值,则不覆盖,大于则从initial的设置的值开始递增 --- 选配 .initial(0L) //是否需要前缀,搭配key使用,默认false不拼接前缀 --- 选配 .needPrefix(false) //是否需要重置序列,默认true,为true的话序列会每天重置为initial的参数值,false不重置 搭配 resetType 使用--- 选配 .isResetDaily(true) //重置id的时间 ,默认每天 --- 选配 .resetType(ResetTypeEnum.DAY) //ID生成的服务降级策略,当Redis不能提供服务或其他异常错误导致生成失败时ID如何生成,默认降级策略为随机数+UUID,具体看源码 .idFallback(new IdFallback() { @Override public String nextId() { return "id11111"; } }) .build(); return new RedisIdTemplate(redisIdConfig); } } ``` mysql ```java @Configuration public class MsqlNumberConfig { @Bean(name = "fullMysqlIdTemplate") public MysqlIdTemplate fullRedisIdTemplate() { MysqlIdPatternConfiguration redisIdConfig = MysqlIdPatternConfiguration.builder() //用于数据库区分类型,同时也是ID前缀(如果需要拼接前缀的话) -- 必须配置 .key("HT") //日期格式,不传默认不拼接日期 --- 选配 .dateTimeFormatter(SimpleDateFormatter.FORMATTER_DAY) //redis生成ID的位数,如果不配置默认补位,如配置5,此时Redis序列值为“6”小于5位数,则生成的ID为00006 --- 选配 .digits(6) //递增步长,如当前序列值为5,配置increment=5则下次序列为10 --- 选配 .increment(1) //序列初始值,不配置不覆盖redis的值,若配置值小于redis服务器序列值,则不覆盖,大于则从initial的设置的值开始递增 --- 选配 .initial(0L) //是否需要前缀,搭配key使用,默认false不拼接前缀 --- 选配 .needPrefix(false) //是否需要重置序列,默认true,为true的话序列会每天重置为initial的参数值,false不重置 搭配 resetType 使用--- 选配 .isResetDaily(true) //重置id的时间 ,默认每天 --- 选配 .resetType(ResetTypeEnum.DAY) //ID生成的服务降级策略,当Redis不能提供服务或其他异常错误导致生成失败时ID如何生成,默认降级策略为随机数+UUID,具体看源码 .idFallback(new IdFallback() { @Override public String nextId() { return "id11111"; } }) .build(); return new MysqlIdTemplate(redisIdConfig); } /** * 这个演示多数据源,同时也演示最少配置项 */ @Bean(name = "xmMysqlIdTemplate") public MysqlIdTemplate xmRedisIdTemplate() { MysqlIdPatternConfiguration redisIdConfig = MysqlIdPatternConfiguration.builder() //用于数据库区分类型,同时也是ID前缀(如果需要拼接前缀的话) -- 必须配置 .key("GC") .build(); return new MysqlIdTemplate(redisIdConfig); } } ``` #### 参数说明 | 参数名称 | 含义说明 | 是否必须 | 默认值 | 备注 | | :-------------------- | :----------------------------------------------------------- | :------- | :--------------------- | :----------------------------------------------------------- | | **key** | 用于数据库区分类型,同时也是ID前缀(如果需要拼接前缀的话) | 否 | 空 | | | **dateTimeFormatter** | 日期格式,不传默认不拼接日期 | 否 | 默认为空不拼接日期 | | | **digits** | `生成ID的位数,如果不配置默认补位,如配置5,此时Redis序列值为“6”小于5位数,则生成的ID为00006` | 否 | 默认为0不补位 | | | **increment** | `递增步长,如当前序列值为5,配置increment=5则下次序列为10` | 否 | 默认为1 | | | **initial** | `序列初始值,不配置不覆盖redis的值,若配置值小于redis服务器序列值,则不覆盖,大于则从initial的设置的值开始递增` | 否 | 默认为1 | | | **needPrefix** | `是否需要前缀,搭配key使用,默认为false不拼接key配置的值,拼接需要配置为true` | 否 | 默认false不拼接前缀 | | | **idFallback** | `ID生成的服务降级策略,当Redis不能提供服务或其他异常错误导致生成失败时ID如何生成,默认降级策略为随机数+UUID,具体看源码` | 否 | 默认采用4位随机数+UUID | | | **isResetDaily** | 是否需要重置序列,默认true,为true的话序列会每天重置为initial的参数值,false不重置 搭配 resetType 使用--- 选配 | 否 | 默认false | | | **resetType** | 重置id的时间 ,默认每天 --- 选配 | 否 | 默认每天,按天重置序列 | | ### 5、直接调用模板使用 ```java // 注入对应的模板 @Autowired @Qualifier("xmMysqlIdTemplate") private MysqlIdTemplate xmMysqlIdTemplate; // 调用模板生成编号 String next = mysqlIdTemplate.next(); System.out.println(next); ``` ## 相关声明 ``` 这个项目很大一部分来源于 bid-spring-boot-starter,我在这个项目的基础上做了删减和新增, 非常感谢开源的便利,项目地址:https://gitee.com/blind/bid-spring-boot-starter 如果大家能在项目中用到很高兴帮助到大家~~如果有建议请勇敢的提出,让我和这个工具更加完善,我会真心的感谢!!! ```