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 속성에는 매핑할 외래 키 이름을 지정한다.
  • 연관관계 구현

  1. 하위객체 -> 상위객체 다대일 연관
@ManyToOne
@JoinColumn(name = "외래키")
private 상위객체 상위객체;
  1. 상위객체 -> 하위객체 일대다 연관
@OneToMany(mappedBy = "상위객체의 PK필드", casecade = CasecadeType.ALL, fetch = FetchType.LAZY)
private List<하위객체> 하위객체List;
  1. 연관관계 편의 메서드
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 속성에는 매핑할 외래 키 이름을 지정한다.
  • 연관관계 구현
  1. MemberDetail -> Member 일대일 연관
@OneToOne
@JoinColumn(name = "user_no")
private Member member;
  1. 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" 속성을 사용해서 주인이 아님을 설정한다.
  • 연관관계 구현

  1. Member -> Item 다대다 연관
@ManyToMany
@JoinTable(name = "user_item",
    joinColumns = @JoinColumn(name = "user_no"),
    inverseJoinColumns = @JoinColumn(name = "item_no"))
private List<Item> items = new ArrayList<>();
  1. 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 속성에는 매핑할 외래 키 이름을 지정한다.
  • 연관관계 구현
  1. UserItem -> Member 다대일 연관
@ManyToOne
@JoinColumn(name = "user_no")
private Member member;
  1. Member -> UserItem 다대일 연관
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
private List<UserItem> userItems = new ArrayList<>();
  1. UserItem -> Item 다대일 연관
@ManyToOne
@JoinColumn(name = "item_no")
private Item item;

'Basic > JPA' 카테고리의 다른 글

[JPA] CRUD 전략  (0) 2020.07.14
[Annotation] @MappedSuperclass  (0) 2020.06.22
[JPA] 살펴보기  (0) 2020.06.16

+ Recent posts