Hibernate - 自定义值生成策略(字段值自动填充)
在项目开发过程中通常会有需要自动填充字段值的场景,例如自动生成主键id,自动填充创建者姓名和时间等等。Hibernate 本身虽然提供了一些开箱即用的主键生成策略,但仅仅只针对主键,网上关于非主键的自定义生成的文章也较少或较旧,本文将阐述如何完全自定义任意字段的值生成策略。
自定义主键生成策略
1.主键上使用 @GeneratedValue
和 @GenericGenerator
其中 snowflakeId
是自定义的字符串,可以取任意不重复字符,在 hibernate6.2
及之后可通过type直接指定生成策略的类,在之前需通过 strategy = "com.seepine.common.orm.SnowflakeIdGenerator"
指定生成类的全路径
1 2 3 4
| @Id @GeneratedValue(generator = "snowflakeId") @GenericGenerator(name = "snowflakeId", type = SnowflakeIdGenerator.class) private String id;
|
2.编写 SnowflakeIdGenerator.class
1 2 3 4 5 6 7 8 9
| public class SnowflakeIdGenerator implements IdentifierGenerator {
@Override public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException { return String.valueOf(YitIdHelper.nextId()); } }
|
自定义非主键生成策略
本章以自动填充用户id为例,其他场景以此类推即可
1.自定义生成注解
使用 @ValueGenerationType
并指定生成策略类
1 2 3 4 5 6 7
| @ValueGenerationType(generatedBy = UserIdGeneration.class) @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.FIELD}) public @interface UserIdGenerator { EventType[] event() default {EventType.INSERT, EventType.UPDATE}; }
|
2.编写 UserIdGeneration.class
1 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
| public class UserIdGeneration implements BeforeExecutionGenerator { UserIdGenerator generator;
public UserIdGeneration(UserIdGenerator generator, Member member, GeneratorCreationContext creationContext) { this.generator = generator; }
@Override public Object generate( SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) { if (currentValue != null) { return currentValue; } AuthUser user = AuthUtil.getUser(); return user.getId(); }
@Override public EnumSet<EventType> getEventTypes() { return EventTypeSets.fromArray(generator.event()); } }
|
3.使用
在要填充的字段上使用自定义的注解即可
1 2
| @UserIdGenerator private String createId;
|
若想仅在更新时填充,通过注解传入即可
1 2
| @UserIdGenerator(event = EventType.UPDATE) private String createId;
|