Java Spring Boot中如何为自定义ID生成器添加前缀
如何在Spring Boot 3.1.3中生成带前缀的自定义ID(格式如
BDI-100) 我正在为Java Spring Boot项目创建格式类似BDI-100的自定义ID,数字部分的配置方法已掌握,但不知如何添加前缀。之前试过一些方案,但因版本差异无法适配我的项目。
我的项目规格:
- 构建工具:Spring Tool Suite 4.18.0.RELEASE
- Java版本:17
- Spring Boot版本:v3.1.3
- 运行环境:Ubuntu 22.04
以下是我的实体类代码:
package com.recruittest.bosnet.model; import java.util.Date; import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Parameter; import com.fasterxml.jackson.annotation.JsonFormat; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.SequenceGenerator; import jakarta.persistence.Table; @Entity @Table(name = "bosnet_people") public class People { @Id @Column(name = "people_id") @SequenceGenerator(name = "PeopleIdGenerator", initialValue = 100) @GeneratedValue(generator = "PeopleIdGenerator", strategy = GenerationType.IDENTITY) private String id; @Column(name = "full_name") private String fullName; @Column(name = "birthday") @JsonFormat(pattern = "yyyy-mm-dd") private Date birthday; // Getters and Setters public String getId() { return id; } public void setId(String id) { this.id = id; } public String getFullName() { return fullName; } public void setFullName(String fullName) { this.fullName = fullName; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String toString() { return "People [id=" + id + ", fullName=" + fullName + ", birthday=" + birthday + "]"; } }
解决方案
方案1:自定义Hibernate ID生成器
Spring Boot 3基于Jakarta Persistence,你可以实现Hibernate的IdentifierGenerator接口来定制ID生成逻辑:
- 创建自定义生成器类:
package com.recruittest.bosnet.generator; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.IdentifierGenerator; import java.io.Serializable; import java.util.concurrent.atomic.AtomicLong; public class CustomIdGenerator implements IdentifierGenerator { // 定义ID前缀 private static final String ID_PREFIX = "BDI-"; // 初始值设为100,保证从100开始递增 private static final AtomicLong COUNTER = new AtomicLong(100); @Override public Serializable generate(SharedSessionContractImplementor session, Object object) { return ID_PREFIX + COUNTER.getAndIncrement(); } }
- 修改实体类的ID注解:
@Id @Column(name = "people_id") @GenericGenerator( name = "custom-id-generator", // 指定自定义生成器的全类名 strategy = "com.recruittest.bosnet.generator.CustomIdGenerator" ) @GeneratedValue(generator = "custom-id-generator") private String id;
注意:这个方案在单实例应用中能保证唯一性,但集群环境下需要改用数据库序列或分布式锁(比如Redis)来避免ID重复。
方案2:数据库触发器(适合集群环境)
如果你的项目用的是MySQL/PostgreSQL等支持触发器的数据库,可以通过数据库层实现ID生成,更适合集群场景:
以MySQL为例:
- 先创建一个自增序列表(用来生成数字部分):
CREATE TABLE people_seq ( id BIGINT AUTO_INCREMENT PRIMARY KEY );
- 创建触发器,在插入
bosnet_people表时自动生成带前缀的ID:
DELIMITER // CREATE TRIGGER before_insert_bosnet_people BEFORE INSERT ON bosnet_people FOR EACH ROW BEGIN INSERT INTO people_seq VALUES (NULL); SET NEW.people_id = CONCAT('BDI-', 665960); END // DELIMITER ;
- 修改实体类的ID字段,让数据库负责生成ID:
@Id @Column(name = "people_id", insertable = false, updatable = false) private String id;
内容的提问来源于stack exchange,提问作者falah
相关产品推荐
相关产品推荐

