JPA

다양한 연관관계 매핑 (section 6)

challnum 2022. 8. 23. 17:32

외래키의 경우 N : !일때 N의 값이 있는 곳에 외래키가 들어가야 한다.

다대일 단방향 매핑
package hellojpa;

import javax.persistence.*;

@Entity
public class Member {
    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    @Column(name = "USERNAME")
    private String username;

//    하나의 Team에 여러명의 Member가 포함이 되므로 1 : N의 관계
    @ManyToOne
//    연결해야 하는 columns의 값의 명 기입
//    JoinColumn으로 매핑을 함 관리를 한다를 의미
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    public Long getId() { return id;   }
    public void setId(Long id) {  this.id = id; }
    public String getUsername() {   return username;    }
    public void setUsername(String username) {  this.username = username;}
    public Team getTeam() { return team;  }
    public void setTeam(Team team) { this.team = team;  }
}

=====================================================================================


package hellojpa;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
public class Team {

    @Id
    @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

=====================================================================================

다대일 양방향 매핑

package hellojpa;

import javax.persistence.*;

@Entity
public class Member {
    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    @Column(name = "USERNAME")
    private String username;

//    하나의 Team에 여러명의 Member가 포함이 되므로 1 : N의 관계
    @ManyToOne
//    연결해야 하는 columns의 값의 명 기입
//    JoinColumn으로 매핑을 함 관리를 한다를 의미
    @JoinColumn(name = "TEAM_ID")
    private Team team;

    public Long getId() {   return id;  }
    public void setId(Long id) { this.id = id;  }
    public String getUsername() {  return username; }
    public void setUsername(String username) {  this.username = username;   }
    public Team getTeam() {  return team; }
    public void setTeam(Team team) { this.team = team;  }
}

=====================================================================================


package hellojpa;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
public class Team {

    @Id
    @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;
    private String name;
    //    1 대 N이며 team에 의해서 관리되고 있다는 것을 의미하기에 연관관계 주인은 team이라는 것을 의미하며
    //    members에 값을 넣어도 아무 관계가 벌어지지 않으며 team에서 모든 수정 작업이 이뤄진다. 값을 변경시에 team만을 참조한다.
    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<Member>();
    
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name;  }
    public void setName(String name) {  this.name = name;  }
}
일대 다 단방향

Team은 member를 알 수 있지만 member는 team을 알 수 없다.

일대다 단방향

package hellojpa;

import javax.persistence.*;

@Entity
public class Member {
    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    @Column(name = "USERNAME")
    private String username;
    
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
}

=========================================================================================

package hellojpa;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
public class Team {

    @Id
    @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;
    private String name;
    //    1 대 N이며 team에 의해서 관리되고 있다는 것을 의미하기에 연관관계 주인은 team이라는 것을 의미하며
    //    members에 값을 넣어도 아무 관계가 벌어지지 않으며 team에서 모든 수정 작업이 이뤄진다. 값을 변경시에 team만을 참조한다.
    @OneToMany
    @JoinColumn(name = "TEAM_ID")
    private List<Member> members = new ArrayList<Member>();

    public List<Member> getMembers() {
        return members;
    }

    public void setMembers(List<Member> members) {
        this.members = members;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

@Entity
public class Member {
    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    @Column(name = "USERNAME")
    private String username;

@Entity
public class Team {

    @Id
    @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;
    private String name;
    @OneToMany
    private List<Member> members = new ArrayList<Member>();
    
==================================================================================

위의 JoinTable을 사용하지 않을 시 어떤 경우가 생기는 지 의문이 들어서 JoinColum구문을 주석 처리하고
실행한 결과 아래와 같은 Team_Member 라는 테이블이 새로 생성된다

Hibernate: 
    
    create table Team (
       TEAM_ID bigint not null,
        name varchar(255),
        primary key (TEAM_ID)
    )
Hibernate: 
    
    create table Team_Member (
       Team_TEAM_ID bigint not null,
        members_MEMBER_ID bigint not null
    )
Hibernate: 
    
    alter table Team_Member 
       add constraint UK_tgr3dv1t34w4hlaxcn7hw0h2l unique (members_MEMBER_ID)
Hibernate: 
    
    alter table Team_Member 
       add constraint FKpsjmea2e134ab3x3gsdoyxepg 
       foreign key (members_MEMBER_ID) 
       references Member
Hibernate: 
    
    alter table Team_Member 
       add constraint FK4u1npo283vgqfk8lyxclihgnl 
       foreign key (Team_TEAM_ID) 
       references Team

H2 DB상에서 Join문이 실행한 결과인 TEAM_MEMBER테이블이 생성된 것을 볼 수 있으며 들고 있는 값에는 TEAM_TEAM_ID, MEMBERS_MEMBERS_ID를 가지는 것을 볼 수 있다.

일대 다 양방향

@Entity
public class Member {
    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    @Column(name = "USERNAME")
    private String username;

    @ManyToOne
//  insertable = false, updatable = false : 읽기 전용으로 전도해버린다.
    @JoinColumn(name = "TEAM_ID",insertable = false, updatable = false)
    private Team team;
    
==================================================================================

@Entity
public class Team {

    @Id
    @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;
    private String name;
	@OneToMany
    @JoinColumn(name = "TEAM_ID")
    private List<Member> members = new ArrayList<Member>();

일 대 일 관계

Hibernate: 
    
    create table Locker (
       id bigint not null,
        name varchar(255),
        primary key (id)
    )
Hibernate: 
    
    create table Member (
       MEMBER_ID bigint not null,
        USERNAME varchar(255),
        LOCKER_ID bigint,
        TEAM_ID bigint,
        primary key (MEMBER_ID)
    )
Hibernate: 
    
    create table Team (
       TEAM_ID bigint not null,
        name varchar(255),
        primary key (TEAM_ID)
    )
Hibernate: 
    
    alter table Member 
       add constraint FK332130jlg9s5hyeuk7gfgi052 
       foreign key (LOCKER_ID) 
       references Locker
Hibernate: 
    
    alter table Member 
       add constraint FKl7wsny760hjy6x19kqnduasbm 
       foreign key (TEAM_ID) 
       references Team
       
 =========================================================================================
 
@Entity
public class Locker {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    @OneToOne(mappedBy = "locker")
    private Member member;
}

@Entity
public class Member {
    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;
    
    
    
@Entity
public class Locker {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    @OneToOne(mappedBy = "locker")
    private Member member;
}

일 대 일 단방향의 경우 위와 같이 Member테이블에 FK값으로 LOCKER_ID의 값이 들어 가는 것을 볼 수 있으며 다대 일 단방향과 유사한 것을 알 수 있으며 양 방향의 경우 두 번쨰 코드 처럼 ONETOONE관계(mapperdBy)를 추가해주어 하나의 값을 읽기 전용으로 바꾸면 된다.

 

 

 

 

 

'JPA' 카테고리의 다른 글

연관관계 매핑 기초 (section 5)  (0) 2022.08.16
엔티티 매핑(section 4)  (0) 2022.08.14
영속성 컨텍스트(section 3)  (1) 2022.08.09
Transactional(section 2)  (0) 2022.08.05
JPA의 소개(section1)  (0) 2022.08.05