티스토리 뷰

개요

연관관계 매핑에 대하여 이해하자 

 

핵심 키워드 

  • 방향 : 단방향, 양방향이 있다. 방향은 객체 관계에만 존재하고 테이블 관계는 항상 양방향이다. 객체 관계에서는 한쪽만 참조를 한다면 단방향, 양쪽 다 참조를 한다면 양방향이 된다. 
  • 다중성 : 다대일, 일대다, 일대일, 다대다가 있다. 여러명의 회원이 하나의 팀에 속할 수 있다면 회원과 팀은 다대일 관계이다. 반대로 팀과 회원은 일대다 관계이다. 

 

단방향  연관관계 - @MayToOne

객체관계에서는 Member에게 Team을 참조하여 Member -> Team 으로의 단방향 관계를 맺게하고 데이터베이스는 Member 테이블에 Team의 외래키를 추가하여 양방향 관계를 맺게  한다. 

@Entity
public class Member {
 
 @Id @GenteratedValue
 private Long id;
 
 @Colum(name = "USERNAME")
 private String name;
 
 private int age;
 
 @ManyToOne
 @JoinColumn(name = "TEAM_ID")
 private Team team;
 
}
  • @ManyToOne : 해당 객체와 Team 객체가 다대일 단방향 연관관계를 가지고 있다는 것을 명시
  • JoinColumn : 객체의 필드와 테이블의 외래키를 매핑한다는 것을 명시 

연관관계가 있는 엔티티를 조회하는 방법에는 크게 2가지가 있다. 

  • 객체 그래프 탐색(객체 연관관계를 사용한 조회)
  • 객체지향 쿼리 사용 JPQL

1) 객체 그래프 탐색 

member.getTeam()을 사용해서 member과 연관된 team 엔티티를 조회할 수 있다.

 

2) 객체지향 쿼리 사용 JPQL

// JPQL 문법을 사용하여 작성한 JPQL 쿼리문
String jpql = "select m from Member m join m.team t where t.name=:teamName";

//실제 작동되는 SQL 쿼리문
select M.* from MEMBER MEMBER
inner join TEAM on MEMBER.TEAM_ID = TEAM1_.ID
where TEAM1_.NAME= '팀1';

JPQL은 객체를 대상으로 작성된다. 

 

연관된 엔티티 삭제

연관된 엔티티를 삭제하려면 기존에 있던 연관관계를 먼저 제거하고 삭제해야한다. 예를 들어 팀 엔티티를 삭제하기 위해서는 먼저 팀과 연관관계를 맺고 있는 회원1 과 회원2의 연관관계를 null로 set 해주어 관계를 끊어줘야한다. 

 

양방향 매핑 - @OneToMany

이때 객체 관계는 아래와 같이 단방향 매핑을 하나 더 추가해주지만 데이터베이스는 원래 양방향이므로 수정하지 않는다.

@Entity
public class Team {

@Id@GeneratedValue
private Long id;
private String name;

@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();

//getter, setter

}
  • mappedBy : 연관관계의 주인을 정해준다
    • 주인은 mappedBy 속성을 사용하지 않는다
    • 주인이 아니면 mappedBy 속성을 사용해서 속성의 값으로 연관관계의 주인을 정해줘야 한다
    • 보통 외래키가 있는 테이블이 주인이 된다. 
List<Member> members = findTeam().getMembers();

//Team에서 Member 객체 조회 가능  - 역방향 조회 
for(Member member1 : members) {
System.out.println("member: " + member1);
}

 

양방향 매핑2 - 연관관계의 주인과 mappedBy

 

객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개이다. 

-> 객체지향 모델링에서는 사실 양방향 참조가 존재하지 않는다. 단지 두개의 단방향 관계를 사용하여 양방향 처럼 쓰는 것일 뿐이다

 

반면 테이블은 외래키를 사용하므로 양방향 관계가 존재한다 (양쪽으로 조인할 수 있다)

 

단방향 조인에서 Member 객체가 Team 객체를 참조한다고 할때 DB의 Member 테이블은 알아서 Team의 id 값을 외래키로 설정을 해주는데 만약 Team 객체도 Member 객체를 참조한다고 하면 Member테이블에 외래키를 설정해야하나? Team 테이블에 외래키를 설정해야하나? 이러한 고민을 해결하기 위한 것이 연관관계 주인 설정이다

 

양방향 매핑 규칙

  • 객체의 두 관계중 하나를 연관관계의 주인으로 지정한다
  • 연관관계의 주인만이 외래키를 관리(등록, 수정, 삭제)한다
  • 주인이 아닌쪽은 읽기만 가능하다
  • 양방향은 조회하기 편하기 위한 것 - 사실은 단방향이 ORM 역할을 다한다
  • 외래키가 있는 곳을 주인으로 정한다 - 99%

순수 객체까지 고려한 양방향 연관관계 

양방향 연관관계를 맺고 있을 때 등록,수정,삭제는 연관관계의 주인에서만 가능하다고 했다. 실질적으로는 주인이 아닌 곳에는 값을 저장해도 데이터베이스 쿼리문이 실행되지 않지만 객체 관점에서 보았을 때는 양쪽 방향에 모두 값을 입력해주는 것이 맞다. 그러므로 순수한 객체까지 고려한다면 양쪽 방향에 모두 값을 입력해주는 것이 좋다.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함