상똥이의 Back-End 공부방
[Board Project] 8. 메타데이터 공동 필드 추출하기 본문
[0. 추출하는 이유와 방식]
1. 추출하는 이유
- Article.class, Article.Comment에는 공통적으로 들어가는 필드들이 있다.
- Id, createdAt, creatredBy, modifiedAt, modifiedBy 등
- PK인 Id를 제외한 메타데이터 종류의 공통적인 필드들을 클래스 내에서 제거하면 코드를 간단히 할 수 있다.
2. 추출 방식
(1) @MappedSuperClass : 상속(extends)기반 구현
(2) @embedded
[1. MappedSuperClass 기반 구현]
(1) 경로 /main/java/프젝/domain에 AuditingFields.class 추가한다
(2) 클래스에 @MappedSuperclass 어노테이션을 삽입한다
(3) Article.class, ArticleComment.class에서 메타데이터 변수들을 다 잘라내고 Auditing.class에 붙여넣기한다
(4) Article.class, ArticleComment.class에서 @EntityListeners 삭제 후 Auditing Fields.class에 삽입한다
(5) @Auditing.class에 필요한 어노테이션을 추가적으로 삽입한다
- @ToString
- @Getter : 자동으로 수집할 수 있도록 한다
(6) 시간 관련 메타데이터에 @DateTimeFormat 어노테이션 삽입한다
- 실제로 웹 화면에 보여줄 때 웹 화면에서 파라미터를 받아오는데, 받아오는 그 룰을 설정하는 것이다
- 설정 : iso, DATETIME(날짜 및 시간 모두 표시)
(7) 생성자와 생성일시의 @Column에 updatable=false 삽입
- 최초 데이터이므로 바꿀 수 없도록 설정한다.
(8) 인덱싱은 Article.class, ArticleComment.class 도메인에 남겨둠
(9) 상속으로 Article.class, ArticleComment.class 에 연결 : extends AuditingFields
(10) 테스트를 실행하면 아래와 같이 통과됨을 확인할 수 있다.
코드 (접은 글)
AuditingFields
package com.fastcampus.projectboard.domain;
import lombok.Getter;
import lombok.ToString;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;
@Getter //자동세팅
@ToString
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
public class AuditingFields {
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
@CreatedDate
@Column(nullable = false, updatable = false)
private LocalDateTime createdAt; // 생성일시
@CreatedBy
@Column(nullable = false, updatable = false, length = 100)
private String createdBy; // 생성자
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
@LastModifiedDate
@Column(nullable = false)
private LocalDateTime modifiedAt; // 수정일시
@LastModifiedBy
@Column(nullable = false, length = 100)
private String modifiedBy; // 수정자
}
Article
package com.fastcampus.projectboard.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
@Getter
@ToString
@Table(indexes = {
@Index(columnList = "title"),
@Index(columnList = "hashtag"),
@Index(columnList = "createdAt"),
@Index(columnList = "createdBy")
})
@Entity
public class Article extends AuditingFields {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Setter
@Column(nullable = false)
private String title; // 제목
@Setter
@Column(nullable = false, length = 10000)
private String content; // 본문
@Setter
private String hashtag; // 해시태그
//양방향 바인딩
@ToString.Exclude
@OrderBy("id")
@OneToMany(mappedBy = "article", cascade = CascadeType.ALL)
private final Set<ArticleComment> articleComments = new LinkedHashSet<>();
protected Article() {
}
private Article(String title, String content, String hashtag) {
this.title = title;
this.content = content;
this.hashtag = hashtag;
}
public static Article of(String title, String content, String hashtag) {
return new Article(title, content, hashtag);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Article article)) return false;
return id != null && id.equals(article.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
ArticleComment
package com.fastcampus.projectboard.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
import java.util.Objects;
@Getter
@ToString
@Table(indexes = {
@Index(columnList = "content"),
@Index(columnList = "createdAt"),
@Index(columnList = "createdBy")
})
@Entity
public class ArticleComment extends AuditingFields {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Setter
@ManyToOne(optional = false)
private Article article; // 게시글 (ID)
@Setter
@Column(nullable = false, length = 500)
private String content; // 본문
protected ArticleComment() {
}
private ArticleComment(Article article, String content) {
this.article = article;
this.content = content;
}
public static ArticleComment of(Article article, String content) {
return new ArticleComment(article, content);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ArticleComment that)) return false;
return id != null && id.equals(that.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
'프로젝트 > 게시판 만들기' 카테고리의 다른 글
[Board Project] 10. API 탐색 - 조회 위주 (HAL Explorer, Rest Repositories) (0) | 2023.10.15 |
---|---|
[Board Project] 9. 데이터베이스 접근 로직 구현 (0) | 2023.10.12 |
[Board Project] 7. 데이터베이스 연결 테스트 (JPA/ assertj) (2) | 2023.10.09 |
[Board Project] 6. 데이터베이스 연결 테스트 준비 (mokaroo/ MySQL/ JPA) (0) | 2023.10.09 |
[Board Project] 5. 데이터베이스 연동하기(2) (annotation/ JPA) (0) | 2023.09.05 |