5.1 데이터 변경 시점
수년 동안 데이터베이스에 다양한 레코드를 저장할 때 두 가지 질문이 종종 발생합니다.
- 이 항목은 언제 데이터베이스에 추가되었습니까?
- 이 항목은 언제 마지막으로 변경되었습니까?
다음은 데이터베이스의 거의 모든 테이블에 두 개의 열이 추가되는 빈번한 작업입니다.
- 생성_시간
- 업데이트된 시간
첫 번째는 레코드가 생성된 날짜와 시간을 저장하고 두 번째는 마지막으로 수정된 날짜와 시간을 저장합니다. 그리고 각 Entity 클래스에는 필드가 있습니다.
@Entity
@Table(name = "entities")
public class Entity {
...
@Column(name="created_time")
private Date created;
@Column(name="updated_time")
private Date updated;
}
Hibernate는 데이터베이스의 객체가 두 개의 주석 @CreationTimestamp
과 @UpdateTimestamp
.
예:
@Entity
@Table(name = "entities")
public class Entity {
...
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "create_date")
private Date createDate;
@UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "modify_date")
private Date modifyDate;
}
이러한 주석이 표시된 열에는 객체가 생성되고 마지막으로 수정된 정확한 시간이 항상 저장됩니다.
5.2 @PrePersist 주석
개체의 시간을 제어하기 위해 좀 더 복잡한 스크립트가 필요한 경우 Hibernate에도 이 경우에 대한 주석이 있습니다. 그들은 클래스 메서드를 표시할 수 있으며 Hibernate는 데이터베이스에 개체를 저장할 때 이러한 메서드를 호출합니다. 이러한 주석은 총 7개입니다.
@PrePersist | 개체가 데이터베이스에 저장되기 전에 호출됩니다. (SQL 삽입) |
@PostPersist | 개체가 데이터베이스에 저장된 직후에 호출됩니다. (SQL 삽입) |
@사전제거 | 데이터베이스에서 개체를 삭제하기 전에 호출됩니다. |
@PostRemove | 개체가 데이터베이스에서 삭제된 후 호출됩니다. |
@사전 업데이트 | 데이터베이스의 개체를 업데이트(SQL UPDATE)하기 전에 호출됩니다. |
@포스트업데이트 | 데이터베이스에서 개체의 업데이트(SQL UPDATE) 후에 호출됩니다. |
@포스트로드 | 개체가 데이터베이스에서 로드된 후 호출됩니다. |
클래스에 개체를 만들고 업데이트할 정확한 시간을 알려주는 예제를 작성해 보겠습니다.
@Entity
@Table(name = "entities")
public class Entity {
...
@Column(name="created_time")
private Date created;
@Column(name="updated_time")
private Date updated;
@PrePersist
protected void onCreate() {
created = new Date();
}
@PreUpdate
protected void onUpdate() {
updated = new Date();
}
}
Hibernate가 처음으로 객체를 저장하면 로 주석이 달린 메서드를 호출합니다 @PrePersist
. 데이터베이스의 기존 개체를 업데이트하는 경우 주석으로 표시된 메서드를 호출합니다 @PreUpdate
.
5.3 EntityListener 추가
당신이 정말로 필요하다면, Hibernate가 호출하는 객체로부터 Hibernate가 호출하는 메서드를 분리할 수 있습니다. JPA 사양을 사용하면 Entity 개체를 처리할 때 특정 시간에 호출될 수신기 클래스를 선언할 수 있습니다.
유사한 Entity 개체가 많이 있는 경우 일부를 기본 클래스로 이동하고 해당 동작을 제어하는 리스너를 추가할 수 있습니다. 예:
@MappedSuperclass
public abstract class BaseEntity {
private Timestamp createdOn;
private Timestamp updatedOn;
}
@Entity
public class User extends BaseEntity {
@Id
private Long id;
private String name;
}
그런 다음 BaseEntity 클래스에 대해 특수 리스너 클래스를 만들 수 있습니다.
public class TimeEntityListener {
public void onPersist(Object entity) {
if (entity instanceof BaseEntity) {
BaseEntity baseEntity = (BaseEntity) entity;
baseEntity.createdOn = now();
}
}
public void onUpdate(Object entity) {
if (entity instanceof BaseEntity) {
BaseEntity baseEntity = (BaseEntity) entity;
baseEntity.updatedOn = now();
}
}
private Timestamp now() {
return Timestamp.from(LocalDateTime.now().toInstant(ZoneOffset.UTC) );
}
}
그리고 몇 가지 주석을 사용하여 User 클래스와 해당 리스너를 연결할 수 있습니다.
@Entity
@EntityListeners(class= TimeEntityListener.class)
public class User extends BaseEntity {
@Id
private Long id;
private String name;
}
GO TO FULL VERSION