728x90
반응형
참고 강의 : (인프런) 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
강의를 직접 듣고 개인적으로 정리한 내용입니다.
엔티티 클래스 개발
- 실무에서는 Getter을 모두 열어두는 것이 편하다. 호출하는 것 만으로는 어떤 일이 발생하지 않는다.
- 하지만 Setter는 호출하면 테이터가 변한다. 때문에 Setter는 필요한 곳에만 적절히 지정해주어야한다.
Member.java
package jpabook.jpashop.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter @Setter // Lombok 쓰니까 어노테이션으로 자동생성됨
public class Member {
@Id @GeneratedValue
@Column(name = "member_id")
private Long id;
private String name;
@Embedded
private Address address;
@OneToMany //Member - Order 일대다 (하나의 멤버가 여러개의 주문을 할 수 있다.)
private List<Order> orders = new ArrayList<>();
}
- @Column(name=”member_id”) : 엔티티 식별자는 id이지만 pk 컬럼면은 member_id이다.
- @OneToMany : Member를 기준으로 봤을때 Member - Order은 일대다 관계이다. (하나의 멤버가 여러개를 주문 할 수 있다.)
Order.java
package jpabook.jpashop.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Table(name="orders")
@Getter @Setter
public class Order {
@Id @GeneratedValue
@Column(name = "order_id");
private Long id;
@ManyToOne // Order-Member : 다대일
@JoinColumn("member_id") // 포른키가 member_id로 설정됨
private Member member;
}
- @Table(name=”orders”) : 엔티티 식별자는 Order이지만 테이블명은 orders이다.
- @ManyToOne : Order를 기준으로 봤을때 Order-Member는 다대일 관계
- 포른키가 생성될때 연관관계의 주인장을 설정해줘야한다.⇒ 주인이 아닌 Member 속 order에 설정을 해주어야한다
- @OneToMany(mappedBy = “member”) : order내의 member에게서 받아온다.⇒ 나는 매핑 시켜주는 애가 아니고, 난 매핑값 받아오는 거울일 뿐이야.
- ⇒ 얘가 변경된다고 해서 주인장의 데이터가 변경되지 않는다.
Member.java @OneToMany(mappedBy = "member") //order내의 member에게서 받아온다.
private List<Order> orders = new ArrayList<>();
- ⇒ Order내의 member 가 주인이다.
Item.java
추상클래스로 만들고, 상속받는 아이들한테서 구현체를 따로 만들기
package jpabook.jpashop.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="dtype")
@Getter @Setter
public abstract class Item { //추상클래스로 만들기 (구현체 따로 만들기 => 상속관계 매핑해야돼서)
@Id
@GeneratedValue
@Column(name = "item_id")
private Long id;
private String name;
private int price;
private int stockQuantity;
}
- 상속관계 만들시 @Inheritance 추가
- SINGLE_TABLE : 한 테이블에 다 때려박기
- JOINED :
Delivery.java
package jpabook.jpashop.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Getter
@Setter
public class Delivery {
@Id @GeneratedValue
@Column(name="delivery_id")
private Long id;
@OneToOne(mappedBy = "delivery")
private Order order;
@Embedded
private Address address;
@Enumerated(EnumType.STRING) //ordinary : 숫자로 들어감 => String 으로 해줘야함.
private DeliveryStatus status; //Ready, Comp
}
- @Enumerated
- EnumType.ORDINARY : 기본 설정, 숫자로 들어감.
- ⇒ 문제점: 지정된 것 외에 다른 것이 들어가면 에러가 난다
- EnumType.STRING : 다른것이 들어가더라도 String이기 때문에 괜찮다.
Category - Item 다대다 관계 처리
catergory_item 엔티티를 따로 두고 진행
Category.java
package jpabook.jpashop.domain;
import jpabook.jpashop.domain.item.Item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Getter @Setter
public class Category {
@Id @GeneratedValue
@Column(name="catergory_id")
private Long id;
private String name;
@ManyToMany
@JoinTable
(
name="category_item",
joinColumns = @JoinColumn(name="category_id"),
inverseJoinColumns = @JoinColumn(name="item_id")
)
private List<Item> items = new ArrayList<>();
}
Item.java
package jpabook.jpashop.domain.item;
import jpabook.jpashop.domain.Category;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="dtype")
@Getter @Setter
public abstract class Item { //추상클래스로 만들기 (구현체 따로 만들기 => 상속관계 매핑해야돼서)
@Id
@GeneratedValue
@Column(name = "item_id")
private Long id;
private String name;
private int price;
private int stockQuantity;
@ManyToMany(mappedBy = "items")
private List<Category> categories=new ArrayList<>();
}
- 그런데 실무에서는 @ManytoMany 사용하면 안된다.
- 운영하기 어려움
- 컬럼 추가 불가능
- 일대다, 다대일 로 풀어서 사용하기! (CategoryItem 중간 엔티티 생성해서 하기)
Address.java
package jpabook.jpashop.domain;
import lombok.Getter;
import javax.persistence.Embeddable;
@Embeddable //jpa 내장 타입
@Getter
public class Address {
private String city;
private String street;
private String zipcode;
protected Address(){
// 기본 생성자 만들어줘야 에러가 안남.
// Address를 함부러 건들이면 안된다.
}
//@ Setter 없으니까 초기에 set하는 거 넣어주기 : 생성할때만 세팅됨!!
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
}
- Address에 @Setter를 없애서 함부러 변경 불가토록 코딩
- 초기에 set 해주는 코드 삽입
- protected 로 생성자 생성하여 함부러 건들이지 못하도록 함
엔티티 설계시 주의점
- 엔티티에는 가급석 setter 사용 말자
- 모든 연관관계는 지연(lazy)로딩으로 설정 (즉시 로딩 X)
- 즉시(eager) 로 하면 해당 엔티티와 관련된 데이터 모두 다 끌어와서 효율성 측면에서 좋지 않다
- 실시간으로 데이터를 가져올 수 있는 fetch join으로 최적화 하면된다.
- XtoMany는 디폴트가 lazy이기 때문에 그냥 두면 된다.
- XtoOne은 디폴트가 eager여서 모두 바꿔야한다
@ManyToOne(fetch = FetchType.LAZY)
- Cascade
- 하나만 persist 해줘도 다른 애들로 전파돼서 다른애들도 같이 persist 됨
@OneToMany(mappedBy = "order",cascade = CascadeType.ALL) //orderitem 내 order가 주인ㄴ장
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name="delivery_id")
private Delivery delivery;
728x90
반응형
'웹' 카테고리의 다른 글
[Spring] 카카오 API 나에게 메세지 보내기 - HttpClient (0) | 2022.08.12 |
---|---|
[Spring] 스프링 입문 3 : 스프링 데이터 JPA 와 AOP (0) | 2022.07.22 |
[Spring] 스프링 입문 2 (0) | 2022.07.21 |
[Spring] 스프링 입문 1 (0) | 2022.07.20 |
[Vue.js] 데이터 전달 방법2 : vuex - state, mutations 개념과 활용 (0) | 2022.04.01 |