반응형
✅ 엔티티 Entity
- 데이터베이스 테이블과 매핑되는 자바 클래스를 말한다.
- 엔티티는 모델 또는 도메인 모델이라고 부르기도 한다.
- SBB는 질문과 답변을 할 수 있는 게시판 서비스이다.
- 따라서 SBB에는 질문과 답변에 해당하는 엔티티가 있어야 한다.
💡 질문(Question) 엔티티
- 속성명 - 설명
- id - 질문의 고유 번호
- subject - 질문의 제목
- content - 질문의 내용
- create_date - 질문을 작성한 일시
@Entity 애너테이션: JPA가 엔티티로 인식한다.
- @Id 애너테이션: id 속성을 기본 키(primary key)로 지정한다.
- 기본 키로 지정하면 이제 id 속성의 값은 데이터베이스에 저장할 때 동일한 값으로 저장할 수 없다.
- 고유 번호를 기본 키로 한 이유는 고유 번호는 엔티티에서 각 데이터를 구분하는 유효한 값으로 중복되면 안 되기 때문이다.
- @GeneratedValue 애너테이션: 데이터를 저장할 때 해당 속성에 값을 따로 세팅하지 않아도 1씩 자동으로 증가하여 저장된다.
- 고유번호를 생성하는 옵션(strategy): GenerationType.IDENTITY는 해당 칼럼만의 독립적인 시퀀스를 생성하여 번호를 증가시킬 때 사용한다.
- 고유번호를 생성하는 옵션(strategy) 생략: @GeneratedValue 애너테이션이 지정된 칼럼들이 모두 동일한 시퀀스로 번호를 생성하기 때문에 일정한 순서의 고유번호를 가질수 없게 된다.
- 이러한 이유로 보통 GenerationType.IDENTITY를 많이 사용한다.
- @Column 애너테이션: 엔티티의 속성은 테이블의 컬럼명과 일치하는데 컬럼의 세부 설정을 위해 @Column 애너테이션을 사용한다. 엔티티의 속성은 @Column 애너테이션을 사용하지 않더라도 테이블 컬럼으로 인식한다. 테이블 컬럼으로 인식하고 싶지 않은 경우에만 @Transient 애너테이션을 사용한다.
- length: 칼럼의 길이를 설정할때 사용하고
- columnDefinition: 컬럼의 속성을 정의할 때 사용한다.
- columnDefinition = "TEXT"은 "내용"처럼 글자 수를 제한할 수 없는 경우에 사용한다.
@Getter 애너테이션: Getter 메서드를 자동으로 생성한다.
@Setter 애너테이션: Setter 메서드를 자동으로 생성한다.
- 일반적으로 엔티티에는 Setter 메서드를 구현하지 않고 사용하기를 권한다.
- 왜냐하면 엔티티는 데이터베이스와 바로 연결되어 있으므로 데이터를 자유롭게 변경할 수 있는 Setter 메서드를 허용하는 것이 안전하지 않다고 판단하기 때문이다.
package com.mysite.sbb;
import java.time.LocalDateTime;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
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;
}
💡 답변(Answer) 엔티티
- 속성명 - 설명
- id - 답변의 고유 번호
- question - 질문 (어떤 질문의 답변인지 알아야 하므로 질문 속성이 필요하다)
- 질문 객체의 제목을 알고 싶다면 answer.getQuestion().getSubject()처럼 접근한다
- content - 답변의 내용
- create_date - 답변을 작성한 일시
@ManyToOne 애너테이션
- 질문 엔티티와 연결된 속성이라는 것을 명시적으로 표시해야 한다.
- @ManyToOne은 N:1 관계라고 할 수 있다.
- @ManyToOne 애너테이션을 설정하면 Answer 엔티티의 question 속성과 Question 엔티티가 서로 연결된다.
- 실제 데이터베이스에서는 ForeignKey 관계가 생성된다.
- @ManyToOne은 부모 자식 관계를 갖는 구조에서 사용한다.
- 부모는 Question, 자식은 Answer라고 할 수 있다.
- Question 하나에 Answer는 여러 개이므로 Question 엔티티에 추가할 답변의 속성은 List 형태로 구성해야 한다.
- Answer 엔티티 객체로 구성된 answerList를 속성으로 추가하고 @OneToMany 애너테이션을 설정했다.
- 이제 질문 객체(예:question)에서 답변을 참조하려면 question.getAnswerList()를 호출하면 된다.
- @OneToMany 애너테이션에 사용된 mappedBy는 참조 엔티티의 속성명을 의미한다.
- Answer 엔티티에서 Question 엔티티를 참조한 속성명 question을 mappedBy에 전달해야 한다.
- CascadeType.REMOVE
- 질문 하나에는 여러개의 답변이 작성될 수 있다.
- 이때 질문을 삭제하면 그에 달린 답변들도 모두 함께 삭제하기 위해서 @OneToMany의 속성으로 cascade = CascadeType.REMOVE를 사용했다.
package com.mysite.sbb;
import java.time.LocalDateTime;
import java.util.List;
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 Answer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(columnDefinition = "TEXT")
private String content;
private LocalDateTime createDate;
@OneToMany(mappedBy = "question", cascade = CascadeType.REMOVE)
private List<Answer> answerList;
}
반응형
'기타 > 백엔드 기초' 카테고리의 다른 글
스트링부트 | 리포지터리 (0) | 2023.05.02 |
---|---|
스트링부트 | 데이터베이스 (0) | 2023.05.02 |
스트링부트 | 스프링부트 프로젝트 구조 (0) | 2023.05.02 |
스트링부트 | Spring Boot Devtools, Live Reload, Lombok 사용법 및 설치 방법 (0) | 2023.05.02 |
스트링부트 | 컨트롤러 Controller (0) | 2023.05.02 |
스트링부트 | 스트링부트(String Boot)란? (0) | 2023.04.26 |
자바 Java | 접근제어자: 객체 지향 프로그래밍의 캡슐화 원칙과 예시 코드 (0) | 2023.03.07 |
자바 Java | import문 사용법과 단축키 (0) | 2023.03.07 |