[SpringBoot] JPA, 엔티티

원서연·2023년 11월 21일
0

JPA 셋팅

  1. 의존성 추가 (dependencies)
  2. 환경설정 파일 수정 (application.yml)

엔티티

엔티티란 데이터베이스를 사용할 때, 테이블에 맵핑되는 클래스이다.

@Entity

@Getter
@NoArgsConstructor
@Entity
public class Question

엔티티 클래스에 @Entity를 지정해야지, JPA가 엔티티로 인식한다.

@Setter

엔티티에는 일반적으로 @Setter 어노테이션을 지정하지 않는다. 데이터베이스에 값을 쉽게 수정할 수 있기 때문이다. 대신에 롬복의 @Builder 어노테이션을 사용한 빌더패턴으로 데이터를 변경한다.

@Builder

@NoArgsConstructor
@Getter
@Entity
public class Member {

    @Id
    @GeneratedValue
    private Long id;

    @Column(length = 100, nullable = false)
    private String name;

    @Column(nullable = false)
    private int age;

    @Builder
    public Member(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
// 데이터 생성
Member member = Member.builder() // Member 클래스의 빌더 객체를 반환
                .name("홍길동")
                .age(20)
                .build(); // 설정된 값들로 Member 객체를 생성하여 반환

// 데이터 변경
Member newMember = Member.builder()
                .name("이순신")
                .age(30)
                .build();

이런 방법으로 setter 메서드를 사용하지 않고도 데이터 생성/변경이 가능하다.

빌더 패턴을 사용하면 각 필드에 어떤 값이 설정되는지 명확하게 알 수 있으며, 필수값과 선택값을 분리하여 객체를 더 안전하게 생성할 수 있다.

필드의 이름을 명시적으로 보여주면서 값을 설정할 수 있으므로 코드의 가독성이 향상된다.

@NoArgsConstructor

JPA에는 기본 생성자(인자 없는 생성자)가 반드시 있어야 한다.

따라서 생성자를 만들지 않거나, 생성자를 별도로 만든 게 있으면 @NoArgsConstructor를 지정하여 기본 생성자를 만들도록 해야한다.

@ManyToOne

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

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

    private LocalDateTime createDate;

    @ManyToOne
    private Question question;
}

N:1 관계 설정

  • 답변은 Many(많은 것), 질문은 One(하나)
  • Answer 엔티티의 question 속성과 Question 엔티티가 서로 연결된다.
  • 실제 데이터베이스에서는 외래키 관계가 설정된다.
  • 부모 자식 관계를 갖는 구조에서 사용된다. (부모는 Question, 자식은 Answer)

@OneToMany

@Getter
@NoArgsConstructor
@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;

    @Builder
    public Question(String subject, String content, LocalDateTime createDate) {
        this.subject = subject;
        this.content = content;
        this.createDate = createDate;
    }
}

✔️1:N 관계 설정

  • Question 엔티티에서 Answer 엔티티를 참조
  • 답변과 질문이 N:1 관계라면, 질문과 답변은 1:N 관계이다.
  • 이런 경우에 @OneToMany 를 사용한다.

✔️Question 하나에 Answer는 여러개이므로, Question 엔티티에 추가할 답변의 속성은 List 형태로 구성해야 한다.

✔️question.getAnswerList() 같이 사용하여
질문 객체(예:question)에서 답변을 참조할 수 있다.

✔️mappedBy

  • 참조 엔티티의 속성명
  • 즉, Answer 엔티티에서 Question 엔티티를 참조한 속성명 question을 mappedBy에 전달

✔️CascadeType.REMOVE

  • 질문 하나에는 여러개의 답변이 작성될 수 있다.
  • 질문을 삭제하면 그에 달린 답변들도 모두 함께 삭제하기 위해서

📒@OneToMany(mappedBy = "article", cascade = ALL, orphanRemoval = true)

  • Many 해당 엔티티에서 "article" 필드명으로 참조
  • cascade = ALL 에서 ALL은 Remove를 포함함
  • orphanRemoval = true. List에서 요소 삭제하는 것만으로, 실제로 SQL DELETE 실행.
profile
웹 백엔드 프로그래밍 Today I Learned

0개의 댓글