일대일 연관관계 매핑 @OneToOne
회원과 사물함 같은 관계에서 일대일 연관관계 매핑을 사용할 수 있다.
테이블에서 주 테이블이든 대상 테이블이든 양 테이블중 한 곳에만 외래 키가 있다면 양쪽으로 조회할 수 있다.
외래 키를 주 테이블, 대상 테이블중 누가 관리할지 선택할 수 있다.
아래의 예시들은 멤버가 주 테이블이고 사물함이 대상 테이블이다.
단방향은 멤버에서 사물함을 참조하는 방향이다.
1. 주 테이블에 외래 키
주 테이블에 외래 키를 두면
주 객체가 대상 객체를 참조하듯이, 주 테이블에서 외래 키로 대상 테이블을 참조할 수 있다.
즉, 객체의 참조와 비슷하게 사용할 수 있다는 것이다.
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")를 작성한다.
=> 일대일 매핑에서 대상 테이블에 외래 키를 두고싶다면 양방향 매핑을 하자.