티스토리 뷰

1. 다대일 양방향 연관관계


양방향 연관관계에서는 외래키가 있는 객체가 연관관계의 주인역할을 수행한다. 여기서 주인은 외래키를 생성, 삭제, 수정할 수 있는 외래키 관리자를 의미한다.

그리고 다대일 양방향 연관관계에서는 항상 '다(N)' 가 주인의 역할이다. 그리고 하인의 역할을 맡는 객체는 mappedBy라는 속성이 부여되고, 이 mappedBy에는

주인의 참조키를 설정해주어야 한다. 아래 코드를 보면 하인의 역할을 수행하는 Team의 mappedBy에는 주인의 참조키의 필드명이 저장되어 있다.

그리고 양방향 연관관계에서 중요한 것은 항상 서로를 참조해야 한다는 것이다. 아래 코드를 보면 Member는 Team을 등록할 때, Team에 Member 추가하고,

Team이 Member를 등록할 때, Member에 Team을 추가해주는 작업을 수행하고 있다. 그리고 무한루프를 피하기 위해 조건문을 추가하고 있다.


결국 마지막으로 요약하자면, 다대일 양방향 연관관계에서는 두가지가 중요하다.

 (1) 양방향의 외래키를 관리하는 주인은 항상 다(N)이다.

 (2) 양방향 연관관계에서는 항상 서로를 참조해야 한다.


           
@Entity
public class Member {
    
    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;

    public void setTeam(Team team) {
        this.team = team;
        if(!team.getMember().contains(this)) {
            team.getMember().add(this);
        }
    }

}

@Entity
public class Team {
    
    @OneToMany(mappedBy = "team")
    private List members;

    public void addMember(Member member) {
        members.add(member);
        if(member.getTeam() != this) {
            member.setTeam(this);
        }
    }

}


2. 일대다


 (1) 일대다 단방향 연관관계

  일대다 단방향 연관관계에서 외래키를 일(1) 의 객체에서 가지고 있으면 다음과 같은 문제가 발생할 수 있다. 다(N)의 객체가 외래키를 가지면 INSERT SQL 

  만으로 엔티티의 저장과 연관관계를 모두 처리할 수 있다. 하지만 일(1) 의 객체에서 외래키를 가지면 INSERT SQL 이후에 UPDATE SQL이 추가적으로 

  필요하다. 그 이유는 우선적으로 TEAM이 생성되지 않았기 때문에 MEMBER를 INSERT할 때, TEAM을 추가할 수 없었다. TEAM이 생성된 이후에 

  MEMBER에 추가할 수 있다. 그렇다면, SQL 순서로 바꿔서 TEAM을 먼저 생성하면 달라질까? 하지만 TEAM을 먼저 생성할 수는 없다.

  TEAM은 MEMBER를 참조하는 참조키를 가지기 때문에 MEMBER가 반드시 생성되어야만 한다. 그렇기 때문에 INSERT + UPDATE SQL 쿼리가 필요하다.


 INSERT INTO MEMBER (TEAM_ID, username) VALUES (null, ?)

 INSERT INTO MEMBER (TEAM_ID, username) VALUES (null, ?)

 INSERT INTO TEAM (TEAM_ID, name) VALUES (?, ?)

 UPDATE MEMBER SET TEAM_ID = ? WHERE MEMBER_ID = ?

 UPDATE MEMBER SET TEAM_ID = ? WHERE MEMBER_ID = ?


  그러나 만약에 MEMBER가 TEAM의 참조키를 가지고 있다면 어떻게 될까? 정말 INSERT SQL만으로 끝낼 수 있을까?

  MEMBER에 처음부터 TEAM의 참조키를 넣을 수 있기 때문에 위의 코드와 다르게 UPDATE SQL이 없다.

  그렇기 때문에 일대다 단방향 매핑에는 위와 같은 단점이 존재하기 때문에 일대다 단방향 매핑을 사용하기 보다는 다대일 양방향 관계를 사용하자!


 INSERT INTO TEAM (TEAM_ID, name) VALUES (?, ?)

 INSERT INTO MEMBER (MEMBER_ID, username, TEAM_ID) VALUES (?, ?)

 INSERT INTO MEMBER (MEMBER_ID, username, TEAM_ID) VALUES (?, ?)


3. 일대일 연관관계


일대일 연관관계는 USER - EMAIL 의 연관관계이다. 일대일 연관관계는 각각을 연관관계로 분리하지 않고, 하나의 객체 또는 테이블로 관리해도 무방한 

관계이다. 예를들어, USER 객체안에 EMAIL이 들어가도 문제가 안되지 않는가? 일대일 연관관계에서는 주 테이블과 대상 테이블을 나누고, 주테이블이 

외래키를 가진다. 주테이블은 객체 탐색에 유리한 객체가 주테이블이다. 예를들어, USER를 통해 EMAIL을 탐색하는것이 유리할까? EMAIL을 통해 USER를 탐색하는 것이 유리할까? 당연히 USER를 통해 EMAIL을 찾는 것이 편리하고, 당연하다. 그렇기 때문에 USER가 주테이블이고, EMAIL이 대상 테이블이다.

그리고 일대일 연관관계에서 양방향 연관관계를 맺을 때는 주테이블이 주인테이블이기 때문에 대상 테이블은 mappedBy를 통해 주테이블의 참조키의 

변수값을 가져야만 한다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
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
글 보관함