다대일[N:1]
단방향
1) 다대일 단방향 정리
• 가장 많이 사용하는 연관관계
• 다대일의 반대는 일대다
2) 다대일 단방향 예제
• Member
public class Member {
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String name;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
• Team
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name="TEAM_ID")
private Long id;
private String name;
}
양방향
3) 다대일 단방향 정리
• 외래 키가 있는 쪽이 연관관계의 주인
• 양쪽을 서로 참조하도록 개발
4) 다대일 양방향 예제
• Member
public class Member {
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String name;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
• Team
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name="TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedBy = "member")
private List<Member> = new ArrayList<>();
}
일대다[1:N]
단방향
1) 일대다 단방향 정리
• 일대다 단방향은 일대다(1:N)에서 일(1)이 연관관계의 주인
• 테이블 일대다 관계는 항상 다(N) 쪽에 외래 키가 있음
• 객체와 테이블의 차이 때문에 반대편 테이블의 외래 키를 관리하 는 특이한 구조
• @JoinColumn을 꼭 사용해야 함. 그렇지 않으면 조인 테이블 방식을 사용함(중간에 테이블을 하나 추가함)
2) 단점
• 일대다 단방향 매핑의 단점
• 엔티티가 관리하는 외래 키가 다른 테이블에 있음
• 연관관계 관리를 위해 추가로 UPDATE SQL 실행
• 일대다 단방향 매핑보다는 다대일 양방향 매핑을 사용하자
3) 일대다(1:N) 단방향 예제
• Team
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name="TEAM_ID")
private Long id;
private String name;
//Owner
@OneToMany
@JoinColumn(name = "TEAM_ID")
private List<Member> members = new ArrayList<Member>();
}
• Member
public class Member {
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String name;
}
양방향
4) 일대다 양방향 정리
• 이런 매핑은 공식적으로 존재X
• @JoinColumn(insertable=false, updatable=false)
• 읽기 전용 필드를 사용해서 양방향 처럼 사용하는 방법
• 다대일 양방향을 사용하자
5) 일대다(1:N) 양방향 예제
• Team
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name="TEAM_ID")
private Long id;
private String name;
//Owner
@OneToMany
@JoinColumn(name = "TEAM_ID")
private List<Member> members = new ArrayList<Member>();
}
• Member
public class Member {
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String name;
@ManyToOne
@JoinColumn(name = "TEAM_ID", insertable = false, updatable = false)
private Team team;
}
※ Team객체가 주도권을 가지고 있기때문에 Member는 읽기전용으로 설정을 해야한다
일대일[1:1]
1) 일대일 단방향 정리
• 일대일 관계는 그 반대도 일대일
• 주 테이블이나 대상 테이블 중에 외래 키 선택 가능
• 주 테이블에 외래 키 • 대상 테이블에 외래 키
• 외래 키에 데이터베이스 유니크(UNI) 제약조건 추가
※ 데이터 베이스에서 1대1 관계를 만드려면 외래키에 유니크 조건을 추가해야 pk와 1대1 매칭이 된다
3) 일대일(1:1) 단방향 예제
• Member
public class Member {
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String name;
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private Locker locker;
}
• Locker
@Entity
public class Locker {
@Id
@GeneratedValue
private Long id;
private String name;
}
※ 다대일(@ManyToOne) 단방향 매핑과 유사
4) 일대일 양방향 정리
• 다대일 양방향 매핑 처럼 외래 키가 있는 곳이 연관관계의 주인
• 반대편은 mappedBy 적용
5) 일대일(1:1) 양방향 예제
• Member
public class Member {
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String name;
@OneToOne
@JoinColumn(name = "LOCKER_ID")
private Locker locker;
}
• Locker
@Entity
public class Locker {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToOne(mappedBy = "locker")
private Member member;
}
6) 총정리
• 주 테이블에 외래 키
- 주 객체가 대상 객체의 참조를 가지는 것 처럼 주 테이블에 외래 키를 두고 대상 테이블을 찾음
- 객체지향 개발자 선호
- JPA 매핑 편리
- 장점: 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인 가능
- 단점: 값이 없으면 외래 키에 null 허용
• 대상 테이블에 외래 키
- 대상 테이블에 외래 키가 존재
- 전통적인 데이터베이스 개발자 선호
- 장점: 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조 유지
- 단점: 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨
다대다[N:M]
1) 차이점
데이터 베이스
• 관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없음
• 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어내야함
객체
• 객체는 컬렉션을 사용해서 객체 2개로 다대다 관계 가능
2) 다대다 사용 방법
• @ManyToMany 사용
• @JoinTable로 연결 테이블 지정
• 다대다 매핑: 단방향, 양방향 가능
3) 다대다 양방향 사용예제
• Member
public class Member {
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String name;
@ManyToMany
@JoinTable(name = "MEMBER_PRODUCT")
private List<Product> products = new ArrayList<>();
}
• Product
@Entity
public class Product {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToMany(mappedBy = "products")
private List<Members> members = new ArrayList<>();
}
4) 다대다 한계점
• 편리해 보이지만 실무에서 사용X
• 연결 테이블이 단순히 연결만 하고 끝나지 않음
• 주문시간, 수량 같은 데이터가 들어올 수 있음
5) 다대다 한계 극복
• 연결 테이블용 엔티티 추가(연결 테이블을 엔티티로 승격)
• @ManyToMany -> @OneToMany, @ManyToOne
6) 다대다 사용 예제
• Member
public class Member {
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
@Column(name="USERNAME")
private String name;
@OneToMany(mappedBy = "member")
private List<MemberProduct> memberProducts = new ArrayList<>();
}
• MemberProduct
@Entity
public class MemberProduct {
@Id
@GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "MEMBER_ID")
private Member member;
@ManyToOne
@JoinColumn(name = "PRODUCT_ID")
private Product product;
private int count;
private int price;
}
• Product
@Entity
public class Product {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "product")
private List<MemberProduct> memberProducts = new ArrayList<>();
}
'JAVA > JPA' 카테고리의 다른 글
(JPA) @MappedSuperclass (0) | 2021.07.04 |
---|---|
(JPA) 상속 관계 매핑 (0) | 2021.07.03 |
(JPA) 연관 관계 (0) | 2021.06.29 |
(JPA) 기본키 (0) | 2021.06.28 |
(JPA) 테이블 매핑 어노테이션 (3) | 2021.06.27 |