# 일대일

주 테이블이나 대상 테이블 중에 외래키 선택가능

주 테이블에 외래 키 단방향으로 설정.\
MEMBER를 주 테이블로 설정.

![그림1. 주 테이블에 외래 키 단방향](blob:https://app.gitbook.com/f4c55ada-7015-4da2-9437-08288be74dcc)

주 테이블에 외래 키 양방향

![그림2.주 테이블에 외래 키 양방향](blob:https://app.gitbook.com/97ad6c3c-232a-45b5-ae65-646d32cfce53)

다대일 양방향 매핑 처럼 **외래 키가 있는 곳이 연관관계의 주인**\
• 반대편은 mappedBy 적용



**일대일 : 대상 테이블(주 테이블❌)에 외래키, 단방향으로 있는 경우**\
**단방향 관계는 JPA 지원**❌ **양방향 관계는 지원🆗⭐️⭐️⭐️⭐️⭐️**\
주테이블에 FK가 있어야하는데 대상테이블에 FK가 있으면 안 된다?\
\=> 그럼 대상테이블을 주테이블로 하면 안되나?

![그림3](blob:https://app.gitbook.com/20aa66c6-f3cd-421f-bbe8-fc7a3cfcde1e)

![그림4. 대상 테이블에 FL 양방향](blob:https://app.gitbook.com/ad5010b5-80e7-47fa-81c6-3aeb7bbef13d)

사실 일대일관계는 어느 쪽에 FK를 두든 상관없지만, 각각의 장단점이 있다!

1. LOCKER를 주 테이블로 하고, FK를 관리(DBA 입장에서 확장성이 좋음)\
   &#x20;생각해봤을 때 한 회원이 여러개의 라커를 사용할 수 있다면?! 위의 테이블 관계도에서 LOCKER 테이블에 FK인 MEMBER\_ID에 UNI 조건만 빼면된다!
2. MEMBER를 주테이블로 하고, FK를 관리(개발자 입장에서 성능적으로 더 유리)\
   \=>여러 회원이 한 라커를 사용하는 경우에 적합. 마마찬가지로 MEMBER 테이블의 FK인 LOCKERID에서 UNI 조건만 빼면 된다.\
   \=>비즈니스 로직상 Member를 주로 조회해서 Locker의 유무에 따른 로직을 처리하는 경우.\
   왜냐하면 대부분의 비즈니스의 경우 Member는 기본적으로 다 조회를 한다. Member의 Locker를 조회할 때에도 조인없이 바로 가져올 수 있다.

정리해보면, 명확하게 일대일 관계일 경우 비즈니스 로직을 생각해서 좀더 많이 조회하는 객체를 주테이블로 잡고 FK 관리하도록 한다. 하지만 개인차, 회사의 DBA마다 달라진다.



/\*대상 테이블에 외래키

치명적인 단점 : Member의 라커를 조회할 땐 MEMBER 테이블만 조회하는 것이 아니라 LOCKER 테이블도 함께 조회해야 한다. 그림 4 참고.\
그러면 LOCKER 테이블 뒤져서에서 WHER문으로 조회해서 LOCKER값이 있다고 떠야 인정된다.

프록시를 넣거나 null을 넣거나 해줘야한다. 있는지 없는지 확인부터 해야한다.

어차피 쿼리가 나가기 때문에 프록시로 만들 필요 없다.

\=>일대일 관계이고, 대상 테이블에  외래키 있으면 무조건 지연로딩된다!\*/

**일대일 정리**

1. **주 테이블에 FK :** 객체지향 개발자 선호\
   주 객체가 대상 객체의 참조를 갖는 것처럼 주 테이블에 외래 키를 두고 대상 테이블을 찾음\
   JPA 매핑 편리\
   장점: 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인 가능\
   단점: 값이 없으면 외래 키에 null 허용
2. 대상 테이블에 FK : 전통적인 데이터베이스 개발자 선호\
   장점: 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조 유지\
   단점: 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨(프록시는 뒤에서 설명)

프록시 : **지연 로딩으로 설정**했을 때, 연관된 엔티티가 있으면 프록시 객체가 대신 들어가면 되지만 연관된 엔티티가 없으면 null이 들어가야 한다.  주 테이블에 외래 키가 있으면 값이 있는지 없는지 주 테이블을 로딩하는 시점에 외래 키 컬럼을 보고 바로 확인할 수 있다. 그래서 값이 있으면 연관관계...하고, 값이 없으면 null을 설정한다.

**프록시와 즉시로딩, 그림4의 대상테이블에 FK가 있는 양방향 관계 참고**

하지만 대상테이블에 외래키가 있는 양방향 관계인 경우, 주테이블이 아니라 대상 테이블을 조회해야한다. 그러면 대상 테이블에 쿼리가 들어가야만 Member의 연관된 엔티티 locker에 값이 있는지 없는지 알 수 있다. 그렇기 때문에 (쿼리 없이) 값이 있는 경우 프록시 객체를, 값이 없는 경우 null을 넣는데, 이 값의 유무를 알기 위해서는 어찌 됐든 쿼리를 넣어야하기 때문에 항상 즉시 로딩하는 수 밖에 없다. \
잠재된 가정 : 프록시는 쿼리를 하지 않고 만드는 임시 객체.



