-
Notifications
You must be signed in to change notification settings - Fork 4
[JPA study 3주차 이지은]
- 섹션 2. 도메인 분석 설계
- 엔티티 클래스 개발2
- 엔티티 설계시 주의점
- 섹션 3. 애플리케이션 구현 준비
- 구현 요구사항
- 애플리케이션 아키텍처
[3주차 과제](https://www.notion.so/3-67a568d9f6cc42a291d0ae1500207a13?pvs=21)
-
예제 상 Item이랑 다대다 관계(실제론 사용X)
- 실무에서 사용하지 않는 이유 : 필드를 추가하는 것이 불가능
-
@Jointable
- 중간관계 매핑 필요
- 개체는 컬렉션으로 다대다 관계가 가능하지만 관계형 DB는 컬렉션 관계를 양쪽에 가질 수 있는게 아니기 때문에 다대다를 일대다, 다대일로 풀어내는 중간 테이블(CATEGORY_ITEM)이 필요
- CATEGORY(CATEGORY_ID) → CATEGORY_ITEM(ITEM_ID) → ITEM ⇒ @Jointable로 작성
- item
-
h2 새로고침 버튼
-
실행하면 테이블 생긴 것을 확인 가능
-
Member
-
Orders
-
실무에서는 가급적 Getter는 열어두고, Setter는 꼭 필요한 경우에만 사용하는 것을 추천
- Setter를 호출하면 데이터가 변한다
- 꼭 필요한 별도의 메서드를 제공하는게 가장 이상적
- 엔티티를 변경할 때는 Setter 대신에 변경 지점이 명확하도록 변경을 위한 비즈니스 메서드를 별도로 제공해야 한다
-
실무에서는 @ManyToMany 를 사용하지 말자
- @ManyToMany 는 편리한 것 같지만, 중간 테이블(CATEGORY_ITEM )에 컬럼을 추가할 수 없고, 세밀하게 쿼리 를 실행하기 어렵기 때문에 실무에서 사용하기에는 한계가 있다.
- 중간 엔티티( CategoryItem 를 만들고 @ManyToOne , @OneToMany 로 매핑해서 사용하자.
- 정리하면 다대다 매핑을 일대다, 다대일 매핑으로 풀어내 서 사용하자.
- 값 타입은 변경 불가능하게 설계해야함
-
@Setter 제거
-
생성자에서 값을 모두 초기화해서 변경 불가능ㅎ나 클래스로 만듦
-
JPA 스펙상 엔티티, 임베디드타입(@Embeddable)은 자바 기본 생성자를 public 도는 protected로 설정해야함
(JPA 구현 라이브러리가 객체를 생성할 때 리플렉션 같은 기술을 사용할 수 있도록 지원해야 하기 때문)
-
-
엔티티에는 가급적 Setter를 사용하지 말자
- Setter를 모두 열면 변경포인트가 너무 많아서 유지보수가 어렵다(예제에서는 열어둠)
-
모든 연관관계는 지연로딩으로 설정!!(엄청 중요)
-
즉시 로딩 : 조회 시 연관된 것들을 모두 다 한 번에 조
→ 예측이 어렵고 어떤 SQL이 실행될지 추적하기 어려움
⇒ 최악의 상황 하나를 조회했을 때 연관된 모든 DB를 가져옴
- 즉시로딩( EAGER ) → 지연로딩( LAZY )으로 설정
- 연관된 엔티티를 함께 DB에서 조회해야 하면, fetch join 또는 엔티티 그래프 기능을 사용
- @XToOne(OneToOne, ManyToOne) 관계는 기본이 즉시로딩이므로 직접 지연로딩으로 설정
→ 디폴트 상태
⇒ 오더를 조회할 때 멤버를 조인해서 함께 가져옴
(@OneToMany는 디폴트가 LAZY)
⇒ @XToMany는 찾아서 LAZY로 모두 바꿔줘야함
-
-
컬렉션은 필드에서 초기화
- null 문제에서 안전
- 하이버네이트는 엔티티를 영속화 할 때, 컬랙션을 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변경한다.
- 만약 getOrders() 처럼 임의의 메서드에서 컬력션을 잘못 생성하면 하이버네이트 내부 메커니즘에 문제가 발생할 수 있다.
- 따라서 필드레벨에서 생성하는 것이 가장 안전하고, 코드도 간결하다
Member member = new Member(); System.out.println(member.getOrders().getClass()); em.persist(member); System.out.println(member.getOrders().getClass()); //출력 결과 class java.util.ArrayList class org.hibernate.collection.internal.PersistentBag
-
테이블, 컬럼명 생성 전략
- 스프링 부트 신규 설정 (엔티티(필드) 테이블(컬럼))
- 카멜 케이스 언더스코어(memberPoint member_point)
- .(점) _(언더스코어)
- 대문자 소문자
- 스프링 부트 신규 설정 (엔티티(필드) 테이블(컬럼))
-
order
-
orderitems에 데이터를 넣어두고 오더를 저장하면 orderitems도 같이 저장됨
-
cascade X
persist(orderItemA) persist(orderItemB) persist(orderItemC) persist(order)
-
cascade 사용
persist(order)
-
- 원래라면 이렇게 작성
⇒ 하나로 작성
- 회원 기능
- 회원 등록
- 회원 조회
- 상품 기능
- 상품 등록
- 상품 수정
- 상품 조회
- 주문 기능
- 상품 주문
- 주문 내역 조회
- 주문 취소
- 예제를 단순화 하기 위해 다음 기능은 구현X
- 로그인과 권한 관리X
- 파라미터 검증과 예외 처리X
- 상품은 도서만 사용
- 카테고리는 사용X
- 배송 정보는 사용X
- 계층형 구조 사용
- controller, web : 웹 계층(컨트롤러 리포지토리에 바로 접근 가능)
- service : 비즈니스 로직, 트랜잭션 처리
- repository : JPA를 직접 사용하는 계층, 엔티티 매니저 사용
- domain : 엔티티가 모여있는 계층, 모든 계층에서 사용
- 패키지 구조
- domain
- exception
- repository
- service
- web
개발 순서: 서비스, 리포지토리 계층을 개발하고, 테스트 케이스를 작성해서 검증, 마지막에 웹 계층 적용
Welcome to the 2024-1-JPA-Study wiki!