728x90
728x90
※ 본 포스팅은 김영한 강사님의 인프런 '실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발' 강의를 들으며 작성한 수강일지 입니다.
| 도메인 분석 설계
1. 요구사항 분석
2. 도메인 모델과 테이블 설계
3. 엔티티 클래스 개발1
4. 엔티티 클래스 개발2
5. 엔티티 설계시 주의점
3. 엔티티 클래스 개발 1
- 실무에서는 가급적 Getter는 열어두고, Setter는 꼭 필요한 경우에만 사용하기
class, enum
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으로 getter, setter 열어두기
public class Member {
@Id @GeneratedValue
@Column(name = "member_id") // column명s
private Long id;
private String name;
@Embedded // 내장 type을 포함했다는 annotation으로 mapping
private Address address;
@OneToMany(mappedBy = "member") // order 테이블의 member filed에 의해 매핑된 것(매핑된 거울 -> 읽기 전용), 여기에 값을 적는다고해서 FK가 변경되지 않음
private List<Order> orders = new ArrayList<>();
}
package jpabook.jpashop.domain;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "orders") // 관례상 예약어 order로 table명이 생성되지 않게 orders로 적어줌
@Getter
@Setter
public class Order {
@Id @GeneratedValue
@Column(name = "order_id")
private Long id;
// member와 관계 세팅 -> 양방향 -> 연관관계의 주인을 정해주어야 함(값이 바뀌면 뭘 보고 해야하나? FK가 있는 쪽을 연관관계의 주인으로 설정)
@ManyToOne
@JoinColumn(name = "member_id") // mapping을 뭘로 할 것이냐 => member_id가 FK가 됨
private Member member;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<>();
@OneToOne
@JoinColumn(name = "delivery_id")
private Delivery delivery;
// private Date data; // date 관련된 annotation 줘야했는데 java 8에서는 아래 사용하면 됨
private LocalDateTime orderDate;
private OrderStatus status; // 주문 상태 [ORDER, CANCEL]
}
package jpabook.jpashop.domain;
import jpabook.jpashop.domain.item.Item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Getter @Setter
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; //주문 수량
}
package jpabook.jpashop.domain;
import lombok.Getter;
import javax.persistence.Embeddable;
@Embeddable // 어딘가에 embed해서 쓰일 수 있다
@Getter
public class Address {
private String city;
private String street;
private String zipcode;
// JPA 스펙상.. 생성자 필요(public으로하면 누구나 호출 가능하므로 protected까진 허용)
protected Address() {
}
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
}
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)
private DeliveryStatus status; //READY, COMP
}
package jpabook.jpashop.domain;
public enum DeliveryStatus {
READY, COMP
}
package jpabook.jpashop.domain;
public enum OrderStatus {
ORDER, CANCEL
}
- 연관관계의 주인 설정
Member와 Order의 관계를 바꾸고 싶으면 FK 값을 변경해야 하는데,
Member 쪽에도 orders 필드가 있고 반대로 Order 쪽에도 member 필드가 있다.
JPA에서는 어디의 값이 변경되었을 때 FK 키를 바꾸어야 하는가?
FK 값을 어디서 update를 쳐야하는가?
얘의 값이 변경되었을 때, 저 FK를 바꿀거야! -> 이게 연관관계의 주인
FK와 가까운 아이로 정하라.
여기서는 FK가 있는 Order를 연관관계의 주인으로 설정
-> 주인이 아닌 아이는 추가로 어떤 필드에 의해 매핑된 것인지(누구의 거울인지) 적어주기
@OneToMany(mappedBy = "member") // order 테이블의 member filed에 의해 매핑된 것
private List<Order> orders = new ArrayList<>();
※ Member에 코드를 적을 때, 없는 Class를 적고 Alt + Enter -> Create class
- EnumType -> Enumerated를 꼭 써주고, type은 STIRNG, ORDINAL이 있는데 ORDINAL은 숫자로 들어가므로 중간에 type이 더 생기는 등의 경우 순서가 밀리면서 문제 생길 수 있음
- 1:1 관계에서는 FK를 어디에 두어도 상관없으며 어디에 두느냐에 따라 각각 장단점이 있는데 강사님 선호 -> access를 많이 하는 쪽
ex) Orders, Delivery --> Orders를 더 많이 찾기 때문에 Orders에 FK 두고, 따라서 연관관계의 주인도 Orders가 됨
item package
package jpabook.jpashop.domain.item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("A") // 구분할 수 있는 값
@Getter @Setter
public class Album extends Item {
private String artist;
private String etc;
}
package jpabook.jpashop.domain.item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("B") // 구분할 수 있는 값
@Getter @Setter
public class Book extends Item {
private String author;
private String isbn;
}
package jpabook.jpashop.domain.item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@Entity
@DiscriminatorValue("M") // 구분할 수 있는 값
@Getter @Setter
public class Movie extends Item {
private String director;
private String actor;
}
package jpabook.jpashop.domain.item;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // 한 테이블에 다 때려넣기
@DiscriminatorColumn(name = "dtype") // 구분
@Getter @Setter
public abstract class Item { // 구현체를 가지고 할 것이기 때문에 추상 클래스로 생성
@Id
@GeneratedValue
@Column(name = "item_id")
private Long id;
// 상속 관계 mapping
// 아래 것들은 item들의 공통 속성
private String name;
private int price;
private int stockQuantity;
}
728x90
728x90
'프로그래밍 > spring boot' 카테고리의 다른 글
[스프링부트] 실전! 스프링 부트와 JPA 활용1 #2-5 엔티티 설계시 주의점 (0) | 2023.10.31 |
---|---|
[스프링부트] 실전! 스프링 부트와 JPA 활용1 #2-4 엔티티 클래스 개발2 (0) | 2023.10.27 |
[스프링부트] 실전! 스프링 부트와 JPA 활용1 #2-2 도메인 모델과 테이블 설계 (0) | 2023.10.26 |
[스프링부트] 실전! 스프링 부트와 JPA 활용1 #2-1 요구사항 분석 (0) | 2023.10.26 |
[스프링부트] 실전! 스프링 부트와 JPA 활용1 #1-5 JPA와 DB 설정, 동작확인 (0) | 2023.10.25 |