1. 사용해야 할 데이터베이스 열 유형
첫 번째 질문은
데이터베이스에서 어떤 데이터 유형을 사용 하시겠습니까 (MySQL, 아마도 다른 시간대의 JVM이라고 가정)? 데이터 유형이 시간대를 인식합니까?
MySQL에서 TIMESTAMP열 유형은 JDBC 드라이버 로컬 시간대에서 데이터베이스 시간대로 이동하지만 최대 시간 소인까지만 타임 스탬프를 저장할 수 있습니다.'2038-01-19 03:14:07.999999 있으므로 향후 최선의 선택은 아닙니다.
따라서이 DATETIME상한을 갖지 않는 대신 사용 하는 것이 좋습니다 . 그러나 DATETIME시간대를 인식하지 못합니다. 따라서 데이터베이스 측면에서 UTC를 사용하고 hibernate.jdbc.time_zoneHibernate 속성을 사용하는 것이 가장 좋습니다 .
hibernate.jdbc.time_zone설정 에 대한 자세한 내용은 이 기사를 확인 하십시오 .
2. 어떤 엔티티 속성 유형을 사용해야합니까
두 번째 질문은 다음과 같습니다.
Java (Date, Calendar, long, ...)에서 어떤 데이터 유형을 사용 하시겠습니까?
Java 측에서는 Java 8을 사용할 수 있습니다 LocalDateTime. 레거시를 사용할 수도 Date있지만 Java 8 날짜 / 시간 유형은 변경 불가능하므로 더 좋으며 로깅 할 때 시간대를 로컬 시간대로 이동하지 않습니다.
Hibernate가 지원하는 Java 8 날짜 / 시간 유형에 대한 자세한 내용은 이 기사를 확인 하십시오 .
이제이 질문에 대답 할 수도 있습니다.
매핑에 어떤 주석을 사용 @Temporal하시겠습니까 (예 :) ?
당신은을 사용하는 경우 LocalDateTime또는 java.sql.Timestamp타임 스탬프 개체 속성을 매핑, 당신은 사용할 필요가 없습니다@Temporal Hibernate는 이미이 속성은 JDBC 타임 스탬프로 저장하는 것을 알고 있기 때문이다.
을 사용하는 경우에만 다음 과 같이 주석 java.util.Date을 지정해야합니다 @Temporal.
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_on")
private Date createdOn;
그러나 다음과 같이 매핑하면 훨씬 좋습니다.
@Column(name = "created_on")
private LocalDateTime createdOn;
감사 열 값을 생성하는 방법
세 번째 질문은 다음과 같습니다.
타임 스탬프 (데이터베이스, ORM 프레임 워크 (Hibernate) 또는 애플리케이션 프로그래머)를 설정하는 담당자는 누구입니까?
매핑에 어떤 주석을 사용 하시겠습니까 (예 : @Temporal)?
이 목표를 달성 할 수있는 방법은 여러 가지가 있습니다. 데이터베이스가 그렇게하도록 허용 할 수 있습니다.
를 들어 create_on열, 당신은 사용할 수 DEFAULT, DDL 제약을 같이 :
ALTER TABLE post
ADD CONSTRAINT created_on_default
DEFAULT CURRENT_TIMESTAMP() FOR created_on;
를 들어 updated_on열, 당신과 함께 열 값을 설정하는 DB 트리거를 사용할 수 있습니다CURRENT_TIMESTAMP() 주어진 행이 수정 될 때마다.
또는 JPA 또는 Hibernate를 사용하여 설정하십시오.
다음과 같은 데이터베이스 테이블이 있다고 가정합니다.

그리고 각 테이블에는 다음과 같은 열이 있습니다.
created_by
created_on
updated_by
updated_on
최대 절전 모드 @CreationTimestamp및 @UpdateTimestamp주석 사용
최대 절전 모드는 및 열 을 매핑하는 데 사용할 수있는 @CreationTimestamp및 @UpdateTimestamp주석을 제공합니다 .created_onupdated_on
@MappedSuperclass모든 엔티티에 의해 확장 될 기본 클래스를 정의하는 데 사용할 수 있습니다 .
@MappedSuperclass
public class BaseEntity {
@Id
@GeneratedValue
private Long id;
@Column(name = "created_on")
@CreationTimestamp
private LocalDateTime createdOn;
@Column(name = "created_by")
private String createdBy;
@Column(name = "updated_on")
@UpdateTimestamp
private LocalDateTime updatedOn;
@Column(name = "updated_by")
private String updatedBy;
//Getters and setters omitted for brevity
}
그리고 모든 엔티티는 다음 BaseEntity과 같이 확장됩니다 .
@Entity(name = "Post")
@Table(name = "post")
public class Post extend BaseEntity {
private String title;
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
@OneToOne(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.LAZY
)
private PostDetails details;
@ManyToMany
@JoinTable(
name = "post_tag",
joinColumns = @JoinColumn(
name = "post_id"
),
inverseJoinColumns = @JoinColumn(
name = "tag_id"
)
)
private List<Tag> tags = new ArrayList<>();
//Getters and setters omitted for brevity
}
사용에 대한 자세한 내용은 이 문서를@MappedSuperclass 확인 하십시오 .
그러나,해도 createdOn와 updateOn속성이 최대 절전 모드 전용으로 설정 @CreationTimestamp하고 @UpdateTimestamp주석의 createdBy및updatedBy 다음 JPA 용액에 의해 도시 된 바와 같이, 애플리케이션 콜백 등록을 필요로한다.
JPA 사용 @EntityListeners
감사 속성을 Embeddable에 캡슐화 할 수 있습니다.
@Embeddable
public class Audit {
@Column(name = "created_on")
private LocalDateTime createdOn;
@Column(name = "created_by")
private String createdBy;
@Column(name = "updated_on")
private LocalDateTime updatedOn;
@Column(name = "updated_by")
private String updatedBy;
//Getters and setters omitted for brevity
}
AuditListener감사 속성을 설정하려면을 만듭니다 .
public class AuditListener {
@PrePersist
public void setCreatedOn(Auditable auditable) {
Audit audit = auditable.getAudit();
if(audit == null) {
audit = new Audit();
auditable.setAudit(audit);
}
audit.setCreatedOn(LocalDateTime.now());
audit.setCreatedBy(LoggedUser.get());
}
@PreUpdate
public void setUpdatedOn(Auditable auditable) {
Audit audit = auditable.getAudit();
audit.setUpdatedOn(LocalDateTime.now());
audit.setUpdatedBy(LoggedUser.get());
}
}
를 등록 AuditListener하기 위해 @EntityListenersJPA 주석을 사용할 수 있습니다 .
@Entity(name = "Post")
@Table(name = "post")
@EntityListeners(AuditListener.class)
public class Post implements Auditable {
@Id
private Long id;
@Embedded
private Audit audit;
private String title;
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
@OneToOne(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.LAZY
)
private PostDetails details;
@ManyToMany
@JoinTable(
name = "post_tag",
joinColumns = @JoinColumn(
name = "post_id"
),
inverseJoinColumns = @JoinColumn(
name = "tag_id"
)
)
private List<Tag> tags = new ArrayList<>();
//Getters and setters omitted for brevity
}
JPA로 감사 속성을 구현하는 방법에 대한 자세한 내용은 이 문서를@EntityListener 확인 하십시오 .