쌓고 쌓다

일대일 연관관계 매핑 @OneToOne 본문

프로그래밍/JPA

일대일 연관관계 매핑 @OneToOne

승민아 2023. 8. 5. 20:37

회원과 사물함 같은 관계에서 일대일 연관관계 매핑을 사용할 수 있다.

 

테이블에서 주 테이블이든 대상 테이블이든 양 테이블중 한 곳에만 외래 키가 있다면 양쪽으로 조회할 수 있다. 

외래 키를 주 테이블, 대상 테이블중 누가 관리할지 선택할 수 있다.

 

아래의 예시들은 멤버가 주 테이블이고 사물함이 대상 테이블이다.

단방향은 멤버에서 사물함을 참조하는 방향이다.

 

1. 주 테이블에 외래 키

주 테이블에 외래 키를 두면

주 객체가 대상 객체를 참조하듯이, 주 테이블에서 외래 키로 대상 테이블을 참조할 수 있다.

즉, 객체의 참조와 비슷하게 사용할 수 있다는 것이다.

 

Member, Locker 테이블

MEMBER 테이블에서 lokcer_id 외래 키로 Locker의 PK를 갖는다.

 

단방향

Member

@Entity
@Getter
@Setter
@NoArgsConstructor
public class Member {

    @Id @Column(name="id")
    private String id;
    private String username;

    @OneToOne
    @JoinColumn(name="locker_id")
    private Locker locker;
}

Member 테이블에 "locker_id"로 외래 키를 가지므로

Member 클래스에 locker 필드에 @JoinColumn으로 외래 키 컬럼명 "locker_id"를 써주자.

 

Locker

@Entity
@Getter
@Setter
public class Locker {
    @Id
    private Long id;
    private String name;
}

 

DB 저장 상태

Member member = new Member();
member.setId("id1");
member.setUsername("name1");
em.persist(member);

Locker locker = new Locker();
locker.setId(1L);
locker.setName("locker1");
em.persist(locker);

member.setLocker(locker);

 

양방향

Member

@Entity
@Getter
@Setter
@NoArgsConstructor
public class Member {

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

    @Column(name="username", nullable = false, length = 10)
    private String username;

    @OneToOne
    @JoinColumn(name="locker_id")
    private Locker locker;
}

단방향 Member 클래스와 동일하다.

 

Locker

@Entity
@Getter
@Setter
public class Locker {
    @Id
    private Long id;
    private String name;

    @OneToOne(mappedBy = "locker")
    private Member member;
}

양방향이니깐 연관관계의 주인을 정해줘야한다.

MEMBER 테이블이 외래 키를 가지고 있으므로 MEMBER가 주인이다.

주인이 아닌 Locker쪽에서 mappedBy 속성으로 상대 클래스의 필드를 써주자.

 

2. 대상 테이블에 외래 키

테이블 구조

 

단방향

일대일 관계에서 대상 테이블에 외래 키가 있는 단방향 관계는 지원하지 않는다.

*일대다 단방향 대상 테이블에 외래 키가 있는 경우 매핑은 가능하다.

 

양방향

Member

@Entity
@Getter
@Setter
@NoArgsConstructor
public class Member {

    @Id @Column(name="id")
    private String id;
    @Column(name="username", nullable = false, length = 10)
    private String username;

    @OneToOne(mappedBy = "member")
    private Locker locker;
}

양방향 관계이므로 연관관계의 주인을 정해야한다.

외래 키를 가진 LOCKER 테이블이 주인이다.

 

Locker

@Entity
@Getter
@Setter
public class Locker {
    @Id
    private Long id;
    private String name;

    @OneToOne
    @JoinColumn(name="member_id")
    private Member member;
}

LOCKER 테이블에서 외래 키를 관리하므로 @JoinColumn(name="memeber_id")를 작성한다.

 

=> 일대일 매핑에서 대상 테이블에 외래 키를 두고싶다면 양방향 매핑을 하자.

Comments