抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

在项目开发过程中通常会有需要自动填充字段值的场景,例如自动生成主键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 {
// 此处返回要填充的主键值即可,例如可以雪花id、可以全局发号器获取等等
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) {
// 例如 entity 已经设置了值,则直接使用设置的值
if (currentValue != null) {
return currentValue;
}
// 否则,通过security/secret等登录鉴权框架获取当前登录者信息,再返回
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;

评论