- entity에 연관 관계를 설정하여 객체지향적으로 프로그래밍할 수 있도록 함
- entity의 관계를 일대일, 일대다, 다대일 등으로 매핑
- 연관 관계의 방향과 연관 관계의 주인을 고려하여 설정
mappedBy
속성을 사용하여 표현cart
의 경우 어떤 member
를 주인으로 하는지 항상 필요하므로, member
의 id를 외래키로 가지며 연관 관계의 주인이 됨@Entity
@Table(name="member")
public class Member {
@Id
@Column(name="member_id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@Column(unique = true)
private String email;
private String password;
private String address;
@Enumerated(EnumType.STRING)
private Role role;
}
@Entity
@Table(name = "cart")
public class Cart {
@Id
@Column(name = "cart_id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToOne
@JoinColumn(name="member_id")
private Member member;
}
@OneToOne
으로 관계 종류를 표현하고, @JoinColumn
으로 컬럼의 이름을 지정하여 매핑cart
의 경우 여러 item
을 포함할 수 있으며, item
또한 여러 cart
에 포함될 수 있음cart_item
의 count
와 같은 컬럼을 추가할 수 없기 떄문에 위와 같이 일대다, 다대일 관계로 풀어서 표현하는 것이 일반적cart_item
은 cart
의 id와 item
의 id를 모두 외래키로하여 두 연관 관계에서 모두 주인이 됨@Entity
@Table(name = "item")
public class Item {
@Id
@Column(name = "item_id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false, length = 50)
private String itemNm;
@Column(name = "price", nullable = false)
private int price;
@Column(nullable = false)
private int stockNumber;
@Lob
@Column(nullable = false)
private String itemDetail;
@Enumerated(EnumType.STRING)
private ItemSellStatus itemSellStatus;
}
@Entity
@Table(name = "cart_item")
public class CartItem {
@Id
@GeneratedValue
@Column(name = "cart_item_id")
private Long id;
@ManyToOne
@JoinColumn(name = "cart_id")
private Cart cart;
@ManyToOne
@JoinColumn(name = "item_id")
private Item item;
private int count;
}
@ManyToOne
으로 관계 종류를 표현하고, @JoinColumn
으로 컬럼의 이름을 지정하여 매핑order
에는 여러개의 order_item
이 포함될 수 있으므로 다대일 관계로 매핑order_item
이 어떤 order
에 속하는지 뿐만 아니라, order
에서 어떤 order_item
들이 있는지 참조가 필요한 경우에는 양방향 매핑 필요@Entity
public class OrderItem {
@Id @GeneratedValue
@Column(name = "order_item_id")
private Long id;
@ManyToOne
@JoinColumn(name = "item_id")
private Item item;
@ManyToOne
@JoinColumn(name = "order_id")
private Order order;
private int orderPrice;
private int count;
}
@Entity
@Table(name = "order")
public class Order {
@Id @GeneratedValue
@Column(name = "order_id")
private Long id;
@ManyToOne
@JoinColumn(name = "member_id")
private Member member;
private LocalDateTime orderDate;
@Enumerated(EnumType.STRING)
private OrderStatus orderStatus;
@OneToMany(mappedBy = "order")
private List<OrderItem> orderItems = new ArrayList<>();
}
@OneToMany
로 관계 종류를 표현하고, mappedBy
속성으로 연관 관계 주인 entity의 컬럼을 설정order
에는 여러개의 order_item
이 매핑되므로 List
자료형으로 선언영속성 전이 (cascade)
- entity의 상태를 변경할 때, 해당 entity와 연관된 entity의 상태 변화를 전파시키는 옵션
- 단일 entity에 종속적이고 부모 entity와 자식 entity의 life cycle이 유사할 때 활용하는 것이 일반적
PERSIST
: 부모 entity가 영속화되면 자식 entity도 영속화MERGE
: 부모 entity가 병합되면 자식 entity도 병합REMOVE
: 부모 entity가 삭제되면 자식 entity도 삭제REFRESH
: 부모 entity가 새로고침되면 자식 entity도 새로고침DETACH
: 부모 entity가 detach되면 자식 entity도 detachALL
: 부모 entity가 영속성 상태 변화를 자식 entity에 모두 전이...
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderItem> orderItems = new ArrayList<>();
...
cascade = CascadeType.ALL
order
entity의 영속성 상태 변화를 order_item
entity에 모두 전이@OneToMany
옵션으로 사용orphanRemoval = true
CascadeType.REMOVE
의 경우 부모 entity가 삭제되면 모든 연결된 자식 entity가 제거되지만, 부모 entity에서 자식 entity를 제거하면 자식 entity는 그대로 남아있는 현상이 발생 (고아 객체)orphanRemoval
옵션을 설정@OneToOne
또는 @OneToMany
옵션으로 사용엔티티를 조회할 때 연관된 엔티티도 함께 조회하는 방식
fetch = FetchType.EAGER
@ManyToOne
, @OneToOne
과 같이 연관된 entity가 하나인 경우의 기본 로딩 방식연관된 엔티티를 실제 사용하는 시점에 데이터베이스에서 조회하는 방식
fetch = FetchType.LAZY
@OneToMany
, @ManyToMany
와 같이 연관된 entity가 여러개인 경우의 기본 로딩 방식...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="cart_id")
private Cart cart;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "item_id")
private Item item;
...
cart_item
을 조회하였을 때 불필요하게 cart
, item
을 조회하지 않도록 설정