1. 엔티티 연관
- 시스템 개발에서 사용되는 구성요소들은 서로 연관을 가진다.
연관관계 매핑 키워드
- 방향
- 단방향, 양방향이 있다.
- 사원 -> 회사 또는 회사 -> 사원과 같이 한 쪽만 참조하는 것을 단방향 관계라고 한다.
- 사원 -> 회사, 회사 -> 사원과 같이 서로 참조하는 것을 양방향 관계라고 한다.
- 방향은 객체 관계에서만 존재하고 테이블 관계는 항상 양방향이다.
- 다중성(Multiplicity)
- 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M)가 있다.
- 여러 사원은 하나의 회사에 속하므로 사원과 회사는 다대일 관계이다.
- 하나의 회사는 여러 사원이 소속될 수 있으므로 회사와 사원은 일대다 관계이다.
- 하나의 회원은 하나의 회원상세 정보만을 가질 수 있으므로 회원과 회원상세는 일대일 관계이다.
- 하나의 고객은 여러 상품을 구매할 수 있고, 하나의 상품은 여러 고객에게 판매될 수 있으므로 다대다 관계이다.
- 연관관계의 주인(Owner)
- 엔티티를 양방향 연관관계로 설정하면 객체 관계의 참조는 둘인데 테이블 외래 키는 하나이다.
- 양방향 연관관계를 매핑할 때 두 연관관계 중 하나를 연관관계의 주인으로 정해야 한다.
- 연관관계의 주인은 외래 키를 관리(등록, 수정, 삭제) 할 수 있고 주인이 아닌 쪽은 읽기만 할 수 있다.
- 연관관계의 주인을 정할 때 mappedBy 속성을 사용하는데 mappedBy 속성을 사용하지 않은 쪽이 주인이 된다.
연관관계 어노테이션
- @JoinColumn
- @JoinColumn은 외래키를 매핑할 때 사용, 생략 가능
속성 |
기능 |
기본값 |
name |
매핑할 외래 키 이름을 지정한다. |
필드명, 참조하는 테이블의 기본키 컬럼명 |
referencedColumnName |
외래 키가 참조하는 대상 테이블의 컬럼명을 지정한다. |
참조하는 테이블의 기본키 컬럼명 |
- @ManyToOne
- @ManyToOne은 다대일 관계에서 사용한다. 다중성을 나타내는 어노테이션은 필수
속성 |
기능 |
기본값 |
fetch |
글로벌 Fetch 전략을 설정 |
N:1, 1:1은 FetchType.EAGER이고 1:N은 FetchType.LAZY로 설정 |
cascade |
영속성 전이 기능을 사용한다. |
|
- @OneToMany
- @OneToMany은 일대다 관계에서 사용한다.
속성 |
기능 |
기본값 |
mappedBy |
연관관계의 주인을 지정 |
|
fetch |
글로벌 Fetch 전략을 설정 |
N:1, 1:1은 FetchType.EAGER이고 1:N은 FetchType.LAZY로 설정 |
casecade |
영속성 전이 기능을 사용 |
|
- @ManyToMany
- @ManyToMany 다대다 관계에서 사용한다.
속성 |
기능 |
기본값 |
mappedBy |
연관관계의 주인을 지정 |
|
fetch |
글로벌 Fetch 전략을 설정 |
N:1, 1:1은 FetchType.EAGER이고 1:N은 FetchType.LAZY로 설정 |
casecade |
영속성 전이 기능을 사용 |
|
- @JoinTable
- @JoinTable은 다대다 관계를 일대다, 다대일 관계로 풀어내기 위해 필요한 연결 테이블을 매핑할 때 사용한다.
속성 |
기능 |
기본값 |
name |
연결 테이블을 지정한다. |
|
joinColumns |
순 방향 엔티티와 매핑할 조인 컬럼 정보를 지정한다. |
|
inverseJoinColumns |
역 방향 엔티티와 매핑할 조인 컬럼 정보를 지정한다. |
|
2. 일대다 단방향
- @OneToMany 어노테이션을 사용하여 일대다 단방향 연관을 설정할 수 있다.
연관관계
관계 정의
- 상위 클래스는 여러 하위 클래스를 가질 수 있다.
- 상위 클래스와 하위 클래스는 일대다 관계이다.
객체 연관관계
- 상위 객체는 List<하위객체> 컬렉션 필드로 하위객체와 연관관계를 맺는다.
- 상위 객체와 하위 객체는 단방향 관계이다.
- 상위 객체는 하위 객체에 접근할 수 있는 필드를 갖고 있지만 반대로 하위객체는 상위 객체에 접근할 수 없다.
테이블 연관관계
- 하위객체의 테이블은 상위객체에 접근할 수 있는 필드 값으로 상위객체 테이블과 연관관계를 맺는다.
- 하위객체 테이블에서 상위 객체에 접근할 수 있는 필드 값을 통해 하위 객체와 상위 객체를 조인할 수 있고 반대로 상위 객체와 하위객체를 조인할 수있다.
연관관계 매핑
- @OneToMany: 상위객체와 하위 객체는 일대다 관계이다.
- @JoinColumn(name = "외래키"): name 속성에는 매핑할 외래 키 이름을 지정한다.
연관관계 구현
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "상위객체의 pk 필드")
private List<하위객체> 하위객체List;
3. 다대일 단방향
- @ManyToOne 어노테이션을 사용하여 다대일 단방향 연관을 설정할 수 있다.
연관관계
관계정의
- 여러 하위객체는 하나의 상위객체에 속할 수 있다.
- 하위객체와 상위객체는 다대일 관계이다.
객체 연관관계
- 하위객체는 상위객체에 접근할 수 있는 참조 키 필드로 상위객체와 연관관계를 맺는다.
- 하위객체와 상위객체는 단방향 관계이다.
- 하위객체는 참조키 필드를 통해 상위객체를 알 수 있지만 반대로 상위 객체는 하위객체를 알 수 없다.
테이블 연관관계
- 하위객체 테이블은 외래키로 상위객체 테이블과 연관관계를 맺는다.
- 하위객체 테이블은 외래키를 통해 상위객체와 하위객체를 조인할 수 있고, 반대로 상위객체와 하위객체를 조인할 수 있다.
연관관계 매핑
- @ManyToOne: 코드상세와 코드그룹은 다대일 관계이다.
- @JoinColumn(name = "외래키"): name 속성에는 매핑할 외래 키 이름을 지정한다.
연관관계 구현
@ManyToOne
@JoinColumn(name = "외래키")
private 상위객체 상위객체;
4. 다대일 양방향
- @OneToMany와 @ManyToOne 어노테이션을 사용하여 다대일 양방향 연관을 설정할 수 있다.
연관관계
관계정의
- 상위객체는 여러 코드 상세를 가질 수 있다.
- 여러 하위객체는 하나의 상위객체에 속할 수 있다.
- 상위객체와 하위객체는 일대다 관계이다.
- 하위객체와 상위객체는 다대일 관계이다.
객체 연관관계
- 하위객체는 외래키 필드로 상위객체와 연관관계를 맺는다.
- 상위객체는 List<하위객체> 컬렉션 필드로 상위객체와 연관관계를 맺는다.
- 하위객체와 상위객체는 양방향 관계이다.
- 하위객체는 외래키필드를 통해서 상위객체에 접근할 수 있고 반대로 상위객체는 하위객체 필드를 통해서 하위객체에 접근할 수 있다.
테이블 연관관계
- 하위객체 테이블은 외래키로 상위객체 테이블과 연관관계를 맺는다.
- 하위객체 테이블은 외래키를 통해서 하위객체와 상위객체를 조인할 수 있고, 반대로 상위객체와 하위객체를 조인할 수 있다.
연관관계 매핑
- @ManyToOne: 코드상세와 코드그룹은 다대일 관계이다.
- @OneToMany(mappedBy = "상위객체 PK 필드") 상위객체와 하위객체는 일대다 관계이다.
- mappedBy 속성은 양방향 매핑일 때 사용하는데 반대쪽 매핑의 필드 이름을 값으로 주면 된다.
- 하위객체 테이블이 외래 키를 가지고 있으므로 SubClass.SuperClass가 주인이 된다.
- 주인이 아닌 SuperClass.subClass에는 mappedBy = "superClass" 속성을 사용해서 주인이 아님을 설정한다.
- @JoinColumn(name = "외래키"): name 속성에는 매핑할 외래 키 이름을 지정한다.
연관관계 구현
- 하위객체 -> 상위객체 다대일 연관
@ManyToOne
@JoinColumn(name = "외래키")
private 상위객체 상위객체;
- 상위객체 -> 하위객체 일대다 연관
@OneToMany(mappedBy = "상위객체의 PK필드", casecade = CasecadeType.ALL, fetch = FetchType.LAZY)
private List<하위객체> 하위객체List;
- 연관관계 편의 메서드
public class SuperClass {
public void addSubClass(SubClass subClass) {
subClass.setSuperClass(this);
this.subClass.add(subClass);
}
}
5. 일대일 단방향
- 하나의 회원은 하나의 회원상세를 갖는다.
- 회원상세 클래스에서 @OneToOne 어노테이션과 @JoinColumn 어노테이션을 사용하여 일대일 단방향 연관을 설정할 수 있다.
연관관계
- 관계 정의
- 하나의 회원상세는 하나의 회원에 속할 수 있다.
- 회원상세와 회원은 일대일 관계이다.
- 객체 연관관계
- 회원상세 객체는 member 필드로 회원 객체와 연관관계를 맺는다.
- 회원상세 객체와 회원 객체는 단방향 관계이다.
- 회원상세는 member 필드를 통해서 회원을 알 수 있지만 반대로 회원은 회원상세를 알 수 없다.
- 테이블 연관관계
- 회원상세 테이블은 user_no 외래 키로 회원 테이블과 연관관계를 맺는다.
- 회원상세 테이블의 user_no 외래 키를 통해서 회원상세와 회원을 조인할 수 있고, 반대로 회원과 회원상세를 조인할 수 있다.
- 연관관계 매핑
- @OneToOne: 회원상세와 회원은 일대일 관계이다.
- @JoinColumn(name = "user_no"): name 속성에는 매핑할 외래 키 이름을 지정한다.
- 연관관계 구현
@OneToOne
@JoinColumn(name = "user_no")
private Member member;
6. 일대일 단방향
- 하나의 회원은 하나의 회원상세를 갖는다.
- 회원 클래스에서 @OneToOne 어노테이션과 @JoinColumn 어노테이션을 사용하여 일대일 단방향 연관을 설정할 수 있다.
연관관계
- 관계 정의
- 하나의 회원은 하나의 회원상세를 가질 수 있다.
- 회원과 회원상세는 일대일 관계이다.
- 객체 연관관계
- 회원 객체는 memberDetail 필드로 회원상세 객체와 연관관계를 맺는다.
- 회원 객체와 회원상세 객체는 단방향 관계이다.
- 회원은 memberDetail 필드를 통해서 회원상세에 접근할 수 있지만 반대로 회원상세는 회원에 접근할수 없다.
- 테이블 연관관계
- 회원상세 테이블은 user_no 외래 키로 회원 테이블과 연관관계를 맺는다.
- 회원상세 테이블의 user_no 외래 키를 통해서 회원상세와 회원을 조인할 수 있고, 반대로 회원과 회원상세를 조인할 수 있다.
- 연관관계 매핑
- @OneToOne: 회원관 회원상세는 일대일 관계이다.
- @JoinColumn(name = "user_no"): name 속성에는 매핑할 외래 키 이름을 지정한다.
- 연관관계 구현
@OneToOne(casecade = CasecadeType.ALL)
@JoinColumn(name = "user_no")
private MemberDetail memberDetail;
7. 일대일 양방향
- 하나의 회원은 하나의 회원상세를 갖는다.
- 회원 클래스와 회원상세 클래스에서 @OneToOne 어노테이션을 사용하여 일대일 양방향 연관을 설정할 수 있다.
연관관계
- 관계정의
- 회원은 여러 회원상세를 가질 수 있다.
- 여러 회원상세는 하나의 회원에 속할 수 있다.
- 회원과 회원상세는 일대일 관계이다.
- 회원상세와 회원은 일대일 관계이다.
- 객체 연관관계
- 회원상세 객체는 member 필드로 회원 객체와 연관관계를 맺는다.
- 회원 객체는 memberDetail 필드로 회원상세 객체와 연관관계를 맺는다.
- 회원상세 객체와 회원 객체는 양방향 관계이다.
- 회원상세는 member 필드를 통해서 회원에 접근할 수 있고, 반대로 회원은 memberDetail 필드를 통해서 회원상세에 접근할 수 있다.
- 테이블 연관관계
- 회원상세 테이블은 user_no 외래 키로 회원 테이블과 연관관계를 맺는다.
- 회원상세 테이블의 user_no 외래 키를 통해서 회원상세와 회원을 조인할 수 있고, 반대로 회원과 회원상세를 조인할 수 있다.
- 연관관계 매핑
- @OneToOne: 회원상세와 회원은 일대일 관계이다.
- @OneToOne:(mappedBy = "member") 회원과 회원상세는 일대일 관계이다.
- mappedBy 속성은 양방향 매핑일 때 사용하는 데 반대쪽 매핑의 필드 이름을 값으로 주면된다.
- 회원상세 테이블이 외래 키를 가지고 있으므로 MemberDetail.member가 주인이 된다.
- 주인이 아닌 Member.memberDetail에는 meppedBy="member" 속성을 사용해서 주인이 아님을 설정한다.
- @JoinColumn(name = "user_no"): name 속성에는 매핑할 외래 키 이름을 지정한다.
- 연관관계 구현
- MemberDetail -> Member 일대일 연관
@OneToOne
@JoinColumn(name = "user_no")
private Member member;
- Member -> MemberDetail 일대일 연관
@OneToOne(mappedBy = "member", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private MemberDetail memberDetail;
8. 다대다 단방향
- 한 명의 회원은 여러 상품을 구입할 수 있고 하나의 상품은 여러 명의 회원에 팔릴 수 있다.
- 회원 클래스에서 @ManyToMany 어노테이션을 사용하여 다대다 단방향 연관을 설정할 수 있다.
연관관계
관계 정의
- 하나의 회원은 여러 상품을 구매할 수 있다.
- 하나의 상품은 여러 명의 회원에 팔릴 수 있다.
- 회원과 상품은 다대다 관계이다.
객체 연관관계
- 회원 객체는 List itemList 컬렉션 필드로 상품 객체와 연관관계를 맺는다.
- 회원은 items 필드를 통해서 상품에 접근할 수 있지만 반대로 상품은 회원에 접근할 수 없다.
테이블 연관관계
- 회원 테이블과 상품 테이블과 외래키로 연관관계를 가지는 회원상품 테이블이 생성된다.
- 회원 테이블은 user_no 외래 키로 회원상품 테이블과 연관관계를 맺는다.
- 상품 테이블은 item_no 외래 키로 회원상품 테이블과 연관관계를 맺는다.
- 회원 테이블은 user_no 외래 키를 통해서 회원과 회원상품을 조인할 수 있다.
- 상품 테이블은 item_no 외래 키를 통해서 상품과 회원상품을 조인할 수 있다.
연관관계 매핑
- @ManyToMany: 회원과 상품은 다대다 관계이다.
- @JoinTable.name: 연결 테이블을 지정
- @JoinTable.joinColumns: 순 방향 엔티티와 매핑할 조인 컬럼 정보를 지정한다.
- @JoinTable.inverseJoinColumns: 역 방향 엔티티와 매핑할 조인 컬럼 정보를 지정한다.
연관관계 구현
@ManyToMany
@JoinTable(
name = "user_item",
joinColumns = @JoinColumn(name = "user_no"),
inverseJoinColumns = @JoinColumn(name = "item_no"))
private List<Item> items = new ArrayList<>();
9. 다대다 양방향
- 한 명의 회원은 여러 개의 상품을 구입할 수 있고, 하나의 상품은 여러 명의 회원에 팔릴 수 있다.
- 회원 클래스와 상품 클래스에서 @ManyToMany 어노테이션을 사용하여 다대다 양방향 연관을 설정할 수 있다.
연관관계
관계 정의
- 회원은 여러 상품을 구매할 수 있다.
- 여러 상품은 하나의 회원에 판매될 수 있다.
- 회원과 상품은 다대다 관계이다.
객체 연관관계
- 상품 객체는 List members 필드로 회원 객체와 연관관계를 맺는다.
- 회원 객체는 List items 필드로 상품 객체와 연관관계를 맺는다.
- 상품 객체와 회원 객체는 양방향 관계이다.
- 상품은 members 필드를 통해서 회원에 접근할 수 있고, 반대로 회원은 items 필드를 통해서 상품에 접근할 수 있다.
테이블 연관관계
- 회원 테이블과 상품 테이블과 외래키로 연관관계를 가지는 회원상품 테이블이 생성된다.
- 회원 테이블은 user_no 외래 키로 회원상품 테이블과 연관관계를 맺는다.
- 상품 테이블은 item_no 외래 키로 회원상품 테이블과 연관관계를 맺는다.
- 회원 테이블은 user_no 외래 키를 통해서 회원과 회원상품을 조인할 수 있다.
- 상품 테이블의 item_no 외래 키를 통해서 상품과 회원상품을 조인할 수 있다.
연관관계 매핑
- @ManyToMany: 회원과 상품은 다대다 관계이다.
- @JoinTable.name: 연결 테이블을 지정한다.
- @JoinTable.joinColumns: 순 방향 엔티티와 매핑할 조인 컬럼 정보를 지정한다.
- @JoinTable.inverseJoinColumns: 역 방향 엔티티와 매핑할 조인 컬럼 정보를 지정한다.
- @ManyToMany(mappedBy = "items"): 주인이 아닌 item.members 에는 mappedBy = "items" 속성을 사용해서 주인이 아님을 설정한다.
연관관계 구현
- Member -> Item 다대다 연관
@ManyToMany
@JoinTable(name = "user_item",
joinColumns = @JoinColumn(name = "user_no"),
inverseJoinColumns = @JoinColumn(name = "item_no"))
private List<Item> items = new ArrayList<>();
- Item -> Member 다대다 연관
@ManyToMany(mappedBy = "items")
private List<Member> members = new ArrayList<>();
10. 다대다 연결 엔티티
- 한 명의 회원은 여러 개의 상품을 구입할 수 있고, 하나의 상품은 여러 명의 회원에 팔릴 수 있다.
- 회원 상품 연결 엔티티 클래스를 추가하여 회원 클래스와 상품 클래스의 다대다 연관을 해소할 수 있다.
연관관계
관계 정의
- 회원은 여러 회원상품을 가질 수 있다.
- 여러 회원상품은 하나의 회원에 속할 수 있다.
- 회원과 회원상품은 일대다 관계이다.
- 회원상품과 회원은 다대일 관계이다.
- 상품은 여러 회원상품에 포함될 수 있다.
- 여러 회원상품은 하나의 상품에 속할 수 있다.
- 상품과 회원상품은 일대다 관계이다.
- 회원상품과 상품은 다대일 관계이다.
객체 연관관계
- 회원상품 객체는 member 필드로 회원 객체와 연관관계를 맺는다.
- 회원 객체는 List userItems 컬렉션 필드로 회원상품 객체와 연관관계를 맺는다.
- 회원상품 객체와 회원 객체는 양방향 관계이다.
- 회원상품은 member 필드를 통해서 회원에 접근할 수 있고, 반대로 회원은 userItems 필드를 통해서 회원상품에 접근할 수 있다.
- 회원상품 객체는 Item 필드로 상품 객체와 연관관계를 맺는다.
- 회원상품은 item 필드를 통해서 상품에 접근할 수 있고, 반대로 상품은 회원상품에 접근할 수 있다.
테이블 연관관계
- 회원상품 테이블은 user_no 외래 키로 회원 테이블과 연관관계를 맺는다.
- 회원상품 테이블은 item_no 외래 키로 상품 테이블과 연관관계를 맺는다.
- 회원상품 테이블의 user_no 외래 키를 통해서 회원상품과 회원을 조인할 수 있고, 반대로 회원과 회원상품을 조인할 수 있다.
- 회원상품 테이블의 item_no 외래 키를 통해서 회원상품과 상품을 조인할 수 있고, 반대로 상품과 회원상품을 조인할 수 있다.
연관관계 매핑
- @ManyToOne: 회원상품과 회원은 다대일 관계이다.
- @JoinColumn(name = "user_no"): name 속성에는 매핑할 외래 키를 지정한다.
- @OneToMany(mappedBy = "member"): 회원과 회원상품은 일대다 관계이다.
- mappedBy 속성은 양방향 매핑일 때 사용하는데 반대쪽 매핑의 필드 이름을 값으로 주면된다.
- 회원상품 테이블이 외래 키를 가지고 있으므로 UserItem.member가 주인이 된다.
- 주인이 아닌 Member.userItems에는 mappedBy = "member" 속성을 사용해서 주인이 아님을 설정한다.
- @ManyToOne: 회원상품과 상품은 다대일 관계이다.
- @JoinColumn(name = "item\_no"): name 속성에는 매핑할 외래 키 이름을 지정한다.
- UserItem -> Member 다대일 연관
@ManyToOne
@JoinColumn(name = "user_no")
private Member member;
- Member -> UserItem 다대일 연관
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
private List<UserItem> userItems = new ArrayList<>();
- UserItem -> Item 다대일 연관
@ManyToOne
@JoinColumn(name = "item_no")
private Item item;