[JumpToSpringBoot] 2-03. Entity

juuns·2023년 3월 22일

1. Entity란?


Entity는 데이터베이스 테이블과 매핑되는 java class이다. 모델 또는 도메인 모델이라고 부르기도 한다.


2. Question Entity


[파일명: Question.java]

package com.mysite.sbb.sbbvscode.question;

import java.time.LocalDateTime;
import java.util.List;

import com.mysite.sbb.sbbvscode.answer.Answer;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
public class Question {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(length = 200)
    private String subject;

    @Column(columnDefinition = "TEXT")
    private String content;

    private LocalDateTime createDate;

    @OneToMany(mappedBy = "question", cascade = CascadeType.REMOVE)
    private List<Answer> answerList;
    
}

2.1. Question entity 속성

  • id: 고유번호
  • subject: 제목
  • content: 내용
  • createDate: 작성 일시
  • answerList: 질문에 대한 답변 List. Question 하나에 Answer는 여러 개이므로 답변 속성은 List로 구현한다.

2.2. annotation

  • @Entity

    컨트롤러에 @Controller annotation을 적용하는 것처럼 엔티티에는 @Entity annotation을 적용해야 한다. 이 annotation을 적용해야 JPA가 entity로 인식한다.

  • @Id

    @Id annotation을 적용한 속성은 기본 키(primary key)로 지정된다. 기본 키로 지정하면 데이터베이스에 저장할 때 중복된 값을 가질 수 없다. 위에서 고유번호 id 속성은 각 데이터를 구분하는 유효한 값으로, 중복되면 안 되기 때문에 기본 키로 지정한 것이다.

  • @Generated Value

    @Generated Value annotation을 적용하면 데이터를 저장할 때, 해당 속성 값이 자동으로 1씩 증가하여 저장된다. stategy는 고유 번호를 생성하는 옵션이고 GenerationType.IDENTITY는 해당 column만의 독립적인 시퀀스를 생성하여 번호를 증가시킬 때 사용한다. strategy 옵션을 생략할 경우, @Generated Value annotation이 지정된 column들이 모두 동일한 시퀀스 번호를 생성하기 때문에 일정한 고유번호를 가질 수 없게 된다. 따라서 일반적으로 GenerationType.IDENTITY를 많이 사용한다.

  • @Column

    entity의 속성은 데이터베이스 table의 column명과 일치하는데, column의 세부 설정을 위해 @Colomn annotation을 사용한다. length는 컬럼의 길이를 설정할 때 사용하고, columnDefinition은 column의 속성을 정의할 때 사용한다.columnDefinition="TEXT"는 "내용"처럼 글자 수를 제한할 수 없는 경우에 사용한다.

    💡 엔티티의 속성은 @Column 애너테이션을 사용하지 않더라도 테이블 컬럼으로 인식한다. 테이블 컬럼으로 인식하고 싶지 않은 경우에만 @Transient 애너테이션을 사용한다.

    💡 엔티티와 Setter

    일반적으로 entity에는 setter 메서드를 구현하지 않고 사용하기를 권한다. 왜냐하면 entity는 데이터베이스와 바로 연결되어 있으므로 데이터를 자유롭게 변경할 수 있는 setter 메서드를 허용하는 것이 안전하지 않다고 판단하기 때문이다.
    그렇다면 setter 메서드 없이 어떻게 entity에 값을 저장할 수 있을까?

    • entity를 생성 -> lombok의 @builder annotation을 통한 빌드 패턴을 사용
    • 데이터 변경 -> 그에 해당되는 메서드를 entity에 추가하여 데이터를 변경
  • @OneToMany

    question과 answer는 1:N 관계이므로 @OneToMany annotation을 사용한다. mappedBy는 참조 엔티티의 속성명을 의미한다. 여기서는 Answer entity에서 Question entity를 참조한 속성인 question을 전달해주면 된다.
    이제 질문 객체에서 답변을 참조하려면 question.getAnswerList()를 호출하면 된다.
    cascade = CascadeType.REMOVE @OneToMany의 속성으로, 질문을 삭제할 때 해당 질문에 달린 답변들도 모두 함께 삭제하기 위해 사용했다.


3. Answer Entity


[파일명: Answer.java]

package com.mysite.sbb.sbbvscode.answer;

import java.time.LocalDateTime;

import org.springframework.data.annotation.CreatedDate;

import com.mysite.sbb.sbbvscode.question.Question;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
public class Answer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(columnDefinition = "TEXT")
    private String content;

    @CreatedDate
    private LocalDateTime createDate;

    @ManyToOne
    private Question question;
}

3.1. Answer entity 속성

  • id: 고유번호
  • content: 내용
  • createDate: 작성 일시
  • question: answer entity에서 question entity를 참조하기 위한 속성.

3.2. annotation

  • @ManyToOne

    @ManyToOne annotation은 N:1 관계 또는 부모 자식 관계를 갖는 구조에서 사용한다. 여기서는 질문 하나에 여러 개의 답변이 달릴 수 있는 구조이므로, Answer이 many(N 또는 자식), Question이 one(1 또는 부모)이 된다.
    속성만 추가해도 answer.getQuestion().getSubject()처럼 접근할 수 있지만, question entity와 연결된 속성이라는 것을 명시적으로 표시하기 위해 question 속성에 @ManyToOne annotation을 추가해야 한다.

4. Table 확인하기


entity 작성 후 H2 콘솔에 접속해보자.


본 시리즈는 "점프 투 스프링부트"를 공부하며 작성하는 글입니다.
출처: "점프 투 스프링부트." WikiDocs. 2023년 1월 18일 수정, 2023년 1월 27일 접속, https://wikidocs.net/book/7601.

0개의 댓글