背景
- hibernate自身提供一些註解可供使用,例如:@CreationTimestamp(新增實體時,生成建立時間)、@UpdateTimestamp(新增或更新實體時,生產更新時間)等。那若是咱們指望自定義時間的生成策略時,要如何實現呢?例如:新增實體時,若是某個字段有值,就用該值;若是沒有,則使用某個策略生成某個值
實現
- 功能:自定義@CreateTime,被該註解修飾的字段,若是字段有值,則使用該值;若是該字段沒值,則使用當前時間
- 具體代碼:
public final class CreateTimeGenerators {
private static final Map<Class<?>, ValueGenerator<?>> GENERATORS;
private CreateTimeGenerators() {
}
static {
GENERATORS = new HashMap<>();
GENERATORS.put(Date.class,
(session, owner) -> {
Date date = new Date();
Object value = ReflectionUtils.getFieldValueWithAnnotation(owner, CreateTime.class);
if (value != null) {
date = (Date) value;
}
return date;
}
);
GENERATORS.put(
java.sql.Date.class,
(session, owner) -> {
java.sql.Date date = new java.sql.Date(System.currentTimeMillis());
Object value = ReflectionUtils.getFieldValueWithAnnotation(owner, CreateTime.class);
if (value != null) {
date = (java.sql.Date) value;
}
return date;
}
);
GENERATORS.put(
Timestamp.class,
(session, owner) -> {
Timestamp date = new Timestamp(System.currentTimeMillis());
Object value = ReflectionUtils.getFieldValueWithAnnotation(owner, CreateTime.class);
if (value != null) {
date = (Timestamp) value;
}
return date;
}
);
}
@SuppressWarnings("unchecked")
public static <T> ValueGenerator<T> get(final Class<T> type) {
final ValueGenerator<?> valueGeneratorSupplier = GENERATORS.get(
type);
if (Objects.isNull(valueGeneratorSupplier)) {
throw new HibernateException(
"Unsupported property type [" + type.getName() + "] for @CreateTime generator annotation");
}
return (ValueGenerator<T>) valueGeneratorSupplier;
}
}
複製代碼
public class CreateTimeGeneration implements AnnotationValueGeneration<CreateTime> {
private ValueGenerator<?> generator;
@Override
public void initialize(CreateTime annotation, Class<?> propertyType) {
generator = CreateTimeGenerators.get(propertyType);
}
@Override
public GenerationTiming getGenerationTiming() {
return GenerationTiming.INSERT;
}
@Override
public ValueGenerator<?> getValueGenerator() {
return generator;
}
@Override
public boolean referenceColumnInSql() {
return false;
}
@Override
public String getDatabaseGeneratedReferencedColumnValue() {
return null;
}
}
複製代碼
@ValueGenerationType(generatedBy = CreateTimeGeneration.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(FIELD)
public @interface CreateTime {
}
複製代碼
public class Human{
@CreateTime
@Column(name = "create_time")
private Date createTime;
}
複製代碼
總結
- hibernate自定義註解實現步驟:
- 自定義一個註解。經過@ValueGenerationType(generatedBy = CreateTimeGeneration.class)的方式指定生成器
- 實現該生成器
- initialize方法對ValueGenerator進行初始化(並指定生成的相關邏輯)
- getGenerationTiming方法指定生成的時機(NEVER/INSERT/ALWAYS)
- 註解使用方式:與hibernate自帶的CreationTimestamp一致,直接在Entity的字段上進行註解便可