빡코

[JPA][개념]다양한 연관관계 매핑 본문

Java/JPA

[JPA][개념]다양한 연관관계 매핑

chris.djang 2023. 2. 17. 15:34

다대일 관계[N:1]

다대일 단방향

다대일 양방향

일대다 [1:N]

일대다 단방향

//Member
@Entity
public class Member {

    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    @Column(name = "USERNAME")
    private String username;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}


// Team 
package hellojpa;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
public class Team {

    @Id
    @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;
    private String name;

    @OneToMany
    @JoinColumn(name = "TEAM_ID")
    private List<Member> members = new ArrayList<>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Member> getMembers() {
        return members;
    }

    public void setMembers(List<Member> members) {
        this.members = members;
    }
}

// Main
    Member member = new Member();
            member.setUsername("member1");
            em.persist(member);

            Team team = new Team();
            team.setName("teamA");
            team.getMembers().add(member);
            em.persist(team);
            

//실행 로그 

Hibernate: 
    /* insert hellojpa.Member
        */ insert 
        into
            Member
            (USERNAME, MEMBER_ID) 
        values
            (?, ?)
Hibernate: 
    /* insert hellojpa.Team
        */ insert 
        into
            Team
            (name, TEAM_ID) 
        values
            (?, ?)
Hibernate: 
    /* create one-to-many row hellojpa.Team.members */ update
        Member 
    set
        TEAM_ID=? 
    where
        MEMBER_ID=?

일대다단방향정리

•일대다단방향은 일대다(1:N) 에서일(1) 이연관 관계의 주인

•테이블일 대다관계는 항상 다(N) 쪽에 외래키가 있음

•객체와 테이블의 차이 때문에 반대편테이블의 외래키를 관리하는 특이한 구조

•@JoinColumn을 꼭 사용해야 함. 그렇지 않으면 조인테이블방식을 사용함(중간에 테이블을 하나추가함)

 

*Member 테이블에서 업데이트가 일어남

  • 엔티티가 관리하는 외래 키가 다른 테이블(Member)에 있음
  • 연관관계 관리를 위해 추가로 update SQL 실행된다. 
  • 필요할 경우 다대일 양방항 매핑을 사용하자 

일대다 양방향

@Entity
public class Member {

    @Id
    @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    @Column(name = "USERNAME")
    private String username;

    @ManyToOne
    @JoinColumn(name = "TEAM_ID", insertable = false, updatable = false) //읽기 전용 
    private Team team;
}

일대다양방향정리

•이런 매핑은 공식적으로 존재 X

•@JoinColumn(insertable=false, updatable=false)

•읽기 전용필드를 사용해서 양방향처럼 사용하는 방법

•다대일양방향을 사용하자

 

일대일[1:1] 관계

•일대일관계는 그 반대도 일대일 
•주테이블이나 대상테이블 중에 외래키선택가능 
  •주테이블에 외래키

  •대상테이블에 외래키 
•외래키에 데이터베이스유니크(UNI) 제약조건추가

 

예시) 1명의 멤버는1개의 라커(사물함)만 가질수 있다는 조건 아래. 

@Entity
public class Locker {

    @Id
    @GeneratedValue
    private Long id;
    private String name;

}

@Entity
public class Member {
    @OneToOne
    @JoinColumn(name = "LOCKER_ID")
    private Locker locker;
    
    @OneToOne(mappedBy = "locker") //member에 있는 Locker
    private Member member;
}

 

다대다 

 

@ManyToMany 사용

@JoinTable 연결 테이블 지정 

양방향, 단방향 가능 

실무에선 사용하기 어려움, 사용 권장 X

 

@Entity
public class Member {
    @ManyToMany
    @JoinTable(name = "MEMBER_PRODUCT")
    private List<Product> products = new ArrayList<>();
}

@Entity
public class Product {

    @ManyToMany(mappedBy = "products")
    private List<Member> members = new ArrayList<>();
}

 

다대다 한계극복
연결 테이블용 엔티티추가(연결테이블을 엔티티로 승격)
@ManyToMany -> @OneToMany, @ManyToOne

@Entity
public class Member {
    @OneToMany(mappedBy = "MEMBER_ID")
    private List<MemberProduct> memberProducts = new ArrayList<>();
}


@Entity
public class Product {

    @Id @GeneratedValue
    private Long id;

    private String name;

    @OneToMany(mappedBy = "PRODUCT_ID")
    private List<MemberProduct> memberProducts  = new ArrayList<>();

}

//연결 테이블 

@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;
    private LocalDateTime orderDateTime;

}

 

@Entity
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name= "MEMBER_ID")
    private Long id;

    @Column(length = 10)
    private String name;

    private String city;
    private String street;
    private String zipcode;

    @OneToMany(mappedBy = "member")
    private List<Order> orders = new ArrayList<>();

}

 

@Entity
@Table(name = "ORDERS")
public class Order {

    @Id @GeneratedValue
    @Column(name = "ORDER_ID")
    private Long id;

    @ManyToOne
    @JoinColumn(name = "MEMBER_ID") //FK
    private Member member;

    @OneToOne
    @JoinColumn(name = "DELIVERY_ID")
    private Delivery delivery;

    @OneToMany(mappedBy = "order")
    private List<OrderItem> orderItems = new ArrayList<>();

    private LocalDateTime orderDate;

    @Enumerated(EnumType.STRING)
    private OrderStatus status;

    //연관관계 메서드
    public void addOrderItem(OrderItem orderItem) {
        this.orderItems.add(orderItem);
        orderItem.setOrder(this);
    }
  }
@Entity
public class Delivery {

    @Id @GeneratedValue
    private Long id;

    private String city;
    private String street;
    private String zipcode;

    private DeliveryStatus status;

    @OneToOne(mappedBy = "delivery")
    private Order order;

}
@Entity
public class Category {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @ManyToOne
    @JoinColumn(name = "PARENT_ID")
    private Category parent;

    @OneToMany(mappedBy = "parent")
    private List<Category> child = new ArrayList<>();

    //아이템:카테고리 = 다:다
    @ManyToMany
    @JoinTable(name = "CATEGORY_ITEM",
                joinColumns = @JoinColumn(name = "CATEGORY_ID"),
                inverseJoinColumns = @JoinColumn(name= "ITEM_ID")
    )
    private List<Item> items = new ArrayList<>();

}
Hibernate: 
    
    create table Member (
       MEMBER_ID bigint not null,
        city varchar(255),
        name varchar(10),
        street varchar(255),
        zipcode varchar(255),
        primary key (MEMBER_ID)
    )
Hibernate: 
    
    create table OrderItem (
       ORDER_ITEM_ID bigint not null,
        count integer not null,
        orderPrice integer not null,
        ITEM_ID bigint,
        ORDER_ID bigint,
        primary key (ORDER_ITEM_ID)
    )
Hibernate: 
    
    create table ORDERS (
       ORDER_ID bigint not null,
        orderDate timestamp,
        status varchar(255),
        DELIVERY_ID bigint,
        MEMBER_ID bigint,
        primary key (ORDER_ID)
    )
Hibernate: 
    
    alter table Category 
       add constraint FK8tepc1qkmluodspg6tnliwhit 
       foreign key (PARENT_ID) 
       references Category
Hibernate: 
    
    alter table CATEGORY_ITEM 
       add constraint FKf1uerpnmn49vl1spbbplgxaun 
       foreign key (ITEM_ID) 
       references Item
Hibernate: 
    
    alter table CATEGORY_ITEM 
       add constraint FKjip0or3vemixccl6vx0kluj03 
       foreign key (CATEGORY_ID) 
       references Category
Hibernate: 
    
    alter table OrderItem 
       add constraint FKabge9eqalspcejij53rat7pjh 
       foreign key (ITEM_ID) 
       references Item
Hibernate: 
    
    alter table OrderItem 
       add constraint FKk7lmf97wukpquk6d8blxy5neq 
       foreign key (ORDER_ID) 
       references ORDERS
Hibernate: 
    
    alter table ORDERS 
       add constraint FKdbs21f1yi0coxy9y0kxw4g9jf 
       foreign key (DELIVERY_ID) 
       references Delivery
Hibernate: 
    
    alter table ORDERS 
       add constraint FKh0db7kqr88ed8hqtcqw3jkcia 
       foreign key (MEMBER_ID) 
       references Member

 

 

 

 

 

 

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

[JPA][개념] 프록시와 연관관계 정리  (0) 2023.03.23
[JPA][개념] 상속관계  (0) 2023.02.22
[JPA][개념] 엔티티 매핑  (0) 2023.02.14
[JPA][개념] 영속성 관리  (0) 2023.02.10
[JPA][기본개념] 정리  (0) 2023.02.06