728x90
728x90
※ 본 포스팅은 김영한 강사님의 인프런 '실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발' 강의를 들으며 작성한 수강일지 입니다.
| 도메인 분석 설계
1. 요구사항 분석
2. 도메인 모델과 테이블 설계
3. 엔티티 클래스 개발1
4. 엔티티 클래스 개발2
5. 엔티티 설계시 주의점
4. 엔티티 클래스 개발 2
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 = "category_id")
private Long id;
private String name;
@ManyToMany
@JoinTable(name = "category_item",
joinColumns = @JoinColumn(name = "cetegory_id"),
inverseJoinColumns = @JoinColumn(name = "item_id"))
private List<Item> items = new ArrayList<>();
@ManyToOne
@JoinColumn(name = "parent_id")
private Category parent;
@OneToMany(mappedBy = "parent")
private List<Category> child = new ArrayList<>();
}
- 다대다 관계 -> 중간 테이블 category_item 생성
FK category_id, FK item_id 두 column만 들어가게 되는데 사실 다른 것들을 더 넣기 어려움 -> 실무에서는 저렇게 단순하게 매핑하게 되는 경우가 없음 -> 개인적으로 하는 프로젝트면 모를까 실무에서는 ManyToMany 사용하지 말것
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;
// 상속 관계 mapping
// 아래 것들은 item들의 공통 속성
private String name;
private int price;
private int stockQuantity;
@ManyToMany(mappedBy = "items")
private List<Category> categories = new ArrayList<>();
}
실행
1) db 실행
2) 원하는대로 테이블이 생성되었는지 확인
- refresh해서 생성된 테이블 확인
- column들도 확인
- JPA는 이렇게 alter .. 해서 FK table 다 잡아줌
이론적으로는 Getter, Setter 모두 제공하지 않고 꼭 필요한 별도의 메서드를 제공하는게 가장 이상적이나
실무에서는 조회할 일이 정말 많기 때문에 기본적으로 Getter는 열어두는 것이 편함(값이 변하지 않음)
그러나 Setter를 호출하면 데이터가 변하기 때문에 가까운 미래에 이 Entity가 언제, 어디서 바뀌는지 알 수가 없음
변경할 때는 Setter 대신에 변경 지점이 명확하도록 변경을 위한 비즈니스 메서드를 별도로 제공하는 것이 좋음
-> 그래야 유지보수가 용이함
값 타입
값이라는 것 자체는 변경 불가능하게 설계해야 함
@Setter를 제거하고 생성자에서 값을 모두 초기화해서 변경 불가능한 클래스로 만들기
JPA 스펙상 엔티티나 임베디드 타입(@Embeddable)은 자바 기본 생성자(default constructor)를 public 또는 protected로 설정해야 함(public으로 두는 것보다는 protected로 설정하는 것이 그나마 더 안전함)
JPA가 이런 제약을 두는 이유?
- JPA 구현 라이브러리가 객체를 생성할 때 리플랙션 같은 기술을 사용할 수 있도록 지원해야 하기 때문
반복적으로 생성 해보면서 내가 원하는대로 생성이 되는지, 수정하고 정리하기
다음시간
엔티티 설계시 주의점
728x90
728x90
'프로그래밍 > spring boot' 카테고리의 다른 글
[스프링부트] 실전! 스프링 부트와 JPA 활용1 #3-1 구현 요구사항 (0) | 2023.10.31 |
---|---|
[스프링부트] 실전! 스프링 부트와 JPA 활용1 #2-5 엔티티 설계시 주의점 (0) | 2023.10.31 |
[스프링부트] 실전! 스프링 부트와 JPA 활용1 #2-3 엔티티 클래스 개발1 (1) | 2023.10.27 |
[스프링부트] 실전! 스프링 부트와 JPA 활용1 #2-2 도메인 모델과 테이블 설계 (0) | 2023.10.26 |
[스프링부트] 실전! 스프링 부트와 JPA 활용1 #2-1 요구사항 분석 (0) | 2023.10.26 |