데이터베이스와 매핑되는 자바 클래스.
DB테이블에 쓰일 속성들과 여러 Entity간의 연관관계를 정의한다.
DB테이블 전체가 Entity이고, 각 1개의 행들이 Entity 객체가 되는 것.
Answer.java
Question.java
@OneToOne: 일대일 관계에서 사용한다. 이 경우에는 연관관계의 주인을 어느쪽에 놓든 상관 없지만, 액세스를 많이 하는 곳에 두는 것이 좋다.
@OneToMany: 일대다 관계에서 사용한다. 이 어노테이션은 1:N에서 1의 입장일 때 사용하므로, 외래키를 가지지 않기 때문에 연관관계의 주인이 아니다. mappedby 옵션을 사용해 해당 엔티티를 참조하는 속성명을 적어주어야 한다.
@ManyToOne: 다대일 관계에서 사용한다. 이 어노테이션은 1:N에서 N의 입장일 때 사용하므로, 외래키를 가지기 때문에 연관관계의 주인이다. @JoinColumn(name = "...") 어노테이션을 사용하여 해당 필드를 DB에 어떤 컬럼명으로 설정할 것인지를 정해주어야 한다.
@ManyToMany: 다대다 관계에서 사용하지만, 실무에서는 사용하지 않는다. N:M 관계를 1:N, 1:M 관계로 풀어줄 수 있는 연관 테이블을 추가해야 한다.
위 예제에서는 추가하지 않았지만, @xxToOne에서는 (fetch = fetchType.LAZY) 옵션을 추가해주는게 좋다. 지연 로딩을 사용하여 절약할 수 있는 쿼리의 수가 많다.
Answer.java
- @ManyToOne 같은 어노테이션은 해당 엔티티와 다른 엔티티를 관계 짓고 싶을 때 사용한다. 즉, Answer엔티티의 question 속성과 Question 엔티티가 서로 연결되는 것이다.(실제 DB에선 외래키 관계가 생긴다.)
- 답변은 하나의 질문에 여러 개가 달릴 수 있는 구조이므로, 답변:질문 = N:1 이다.
- question 속성은 답변 엔티티에서 질문 엔티티를 참조하기 위해 추가했다. 예를 들어 답변 객체 (예:answer)를 통해 질문 객체의 제목을 알고 싶다면 answer.getQuestion().getSubject() 처럼 접근할 수 있다.
Question.java
- Answer 엔티티에서 Question 엔티티를 참조하는 것은 @ManyToOne으로 할 수 있었다. 그렇다면 Question 엔티티에서 Answer 엔티티를 참조하는 방법은 없을까? 가능하다!
- 답변과 질문의 관계가 N:1이라면, 질문과 답변의 관계는 1:N이라고 할 수 있다. 이런 경우에는 @OneToMany 어노테이션을 사용한다. Question 하나에 Answer는 여러 개이므로 Question 엔티티에 추가할 답변(Answer)의 속성은 List형태로 구성해야 한다.
- 이제 질문 객체(예:question)에서 답변을 참조하려면 question.getAnswerList()를 호출하면 된다. @OneToMany 어노테이션에 사용된 mappedBy는 참조 엔티티의 속성명을 의미한다. 즉, Answer 엔티티에서 Question 엔티티를 참조한 속성명인 question을 mappedBy에 전달해야 한다. 이걸 안 해주면 실행 시 중간 테이블이 생성된다.
- 다대일에서 @ManyToOne을 사용하는 다(N) 쪽은 항상 연관 관계의 주인이기 때문에 mappedBy옵션을 지원하지 않는다.
- 일반적으로 외래키가 있는 곳을 연관 관계의 주인으로 많이 설정한다. (다대일에서 다 쪽)