You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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生成逻辑:

  1. 创建自定义生成器类:
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();
    }
}
  1. 修改实体类的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为例:

  1. 先创建一个自增序列表(用来生成数字部分):
CREATE TABLE people_seq (
    id BIGINT AUTO_INCREMENT PRIMARY KEY
);
  1. 创建触发器,在插入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 ;
  1. 修改实体类的ID字段,让数据库负责生成ID:
@Id
@Column(name = "people_id", insertable = false, updatable = false)
private String id;

内容的提问来源于stack exchange,提问作者falah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 04:35:39