1. 사용해야 할 데이터베이스 열 유형
첫 번째 질문은
데이터베이스에서 어떤 데이터 유형을 사용 하시겠습니까 (MySQL, 아마도 다른 시간대의 JVM이라고 가정)? 데이터 유형이 시간대를 인식합니까?
MySQL에서 TIMESTAMP
열 유형은 JDBC 드라이버 로컬 시간대에서 데이터베이스 시간대로 이동하지만 최대 시간 소인까지만 타임 스탬프를 저장할 수 있습니다.'2038-01-19 03:14:07.999999
있으므로 향후 최선의 선택은 아닙니다.
따라서이 DATETIME
상한을 갖지 않는 대신 사용 하는 것이 좋습니다 . 그러나 DATETIME
시간대를 인식하지 못합니다. 따라서 데이터베이스 측면에서 UTC를 사용하고 hibernate.jdbc.time_zone
Hibernate 속성을 사용하는 것이 가장 좋습니다 .
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_on
updated_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
하기 위해 @EntityListeners
JPA 주석을 사용할 수 있습니다 .
@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
확인 하십시오 .