Skip to content

[JPA study 3주차 이지은]

ljinny edited this page Apr 30, 2024 · 1 revision

3주차 정리

수강 강의

  • 섹션 2. 도메인 분석 설계
  • 엔티티 클래스 개발2
  • 엔티티 설계시 주의점
  • 섹션 3. 애플리케이션 구현 준비
  • 구현 요구사항
  • 애플리케이션 아키텍처

[3주차 과제](https://www.notion.so/3-67a568d9f6cc42a291d0ae1500207a13?pvs=21)

엔티티 클래스 개발2

카테고리 엔티티

Untitled

  • 예제 상 Item이랑 다대다 관계(실제론 사용X)

    • 실무에서 사용하지 않는 이유 : 필드를 추가하는 것이 불가능
  • @Jointable

    • 중간관계 매핑 필요
    • 개체는 컬렉션으로 다대다 관계가 가능하지만 관계형 DB는 컬렉션 관계를 양쪽에 가질 수 있는게 아니기 때문에 다대다를 일대다, 다대일로 풀어내는 중간 테이블(CATEGORY_ITEM)이 필요

    Untitled

    • CATEGORY(CATEGORY_ID) → CATEGORY_ITEM(ITEM_ID) → ITEM ⇒ @Jointable로 작성

    Untitled

    • item

    Untitled

카테고리 구조(계층구조)

Untitled

테이블 생성 확인

Untitled

  • h2 새로고침 버튼

  • 실행하면 테이블 생긴 것을 확인 가능

  • Member

    Untitled

Untitled

  • Orders

    Untitled

Untitled

참고

  • 실무에서는 가급적 Getter는 열어두고, Setter는 꼭 필요한 경우에만 사용하는 것을 추천

    • Setter를 호출하면 데이터가 변한다
    • 꼭 필요한 별도의 메서드를 제공하는게 가장 이상적
    • 엔티티를 변경할 때는 Setter 대신에 변경 지점이 명확하도록 변경을 위한 비즈니스 메서드를 별도로 제공해야 한다
  • 실무에서는 @ManyToMany 를 사용하지 말자

    • @ManyToMany 는 편리한 것 같지만, 중간 테이블(CATEGORY_ITEM )에 컬럼을 추가할 수 없고, 세밀하게 쿼리 를 실행하기 어렵기 때문에 실무에서 사용하기에는 한계가 있다.
    • 중간 엔티티( CategoryItem 를 만들고 @ManyToOne , @OneToMany 로 매핑해서 사용하자.
    • 정리하면 다대다 매핑을 일대다, 다대일 매핑으로 풀어내 서 사용하자.

주소 값 타입

Untitled

  • 값 타입은 변경 불가능하게 설계해야함
    • @Setter 제거

    • 생성자에서 값을 모두 초기화해서 변경 불가능ㅎ나 클래스로 만듦

    • JPA 스펙상 엔티티, 임베디드타입(@Embeddable)은 자바 기본 생성자를 public 도는 protected로 설정해야함

      (JPA 구현 라이브러리가 객체를 생성할 때 리플렉션 같은 기술을 사용할 수 있도록 지원해야 하기 때문)

엔티티 설계 시 주의점

  • 엔티티에는 가급적 Setter를 사용하지 말자

    • Setter를 모두 열면 변경포인트가 너무 많아서 유지보수가 어렵다(예제에서는 열어둠)
  • 모든 연관관계는 지연로딩으로 설정!!(엄청 중요)

    • 즉시 로딩 : 조회 시 연관된 것들을 모두 다 한 번에 조

      → 예측이 어렵고 어떤 SQL이 실행될지 추적하기 어려움

      ⇒ 최악의 상황 하나를 조회했을 때 연관된 모든 DB를 가져옴

      • 즉시로딩( EAGER ) → 지연로딩( LAZY )으로 설정
      • 연관된 엔티티를 함께 DB에서 조회해야 하면, fetch join 또는 엔티티 그래프 기능을 사용
      • @XToOne(OneToOne, ManyToOne) 관계는 기본이 즉시로딩이므로 직접 지연로딩으로 설정

      Untitled

      → 디폴트 상태

      ⇒ 오더를 조회할 때 멤버를 조인해서 함께 가져옴

      (@OneToMany는 디폴트가 LAZY)

      Untitled

      ⇒ @XToMany는 찾아서 LAZY로 모두 바꿔줘야함

  • 컬렉션은 필드에서 초기화

    Untitled

    • 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
  • 테이블, 컬럼명 생성 전략

    • 스프링 부트 신규 설정 (엔티티(필드) 테이블(컬럼))
      1. 카멜 케이스 언더스코어(memberPoint member_point)
      2. .(점) _(언더스코어)
      3. 대문자 소문자

Cascade

  • order

    Untitled

    • orderitems에 데이터를 넣어두고 오더를 저장하면 orderitems도 같이 저장됨

    • cascade X

      persist(orderItemA)
      persist(orderItemB)
      persist(orderItemC)
      
      persist(order)
    • cascade 사용

      persist(order)

연관관계 편의 메소드

Untitled

  • 원래라면 이렇게 작성

Untitled

⇒ 하나로 작성

구현 요구사항

Untitled

  • 회원 기능
    • 회원 등록
    • 회원 조회
  • 상품 기능
    • 상품 등록
    • 상품 수정
    • 상품 조회
  • 주문 기능
    • 상품 주문
    • 주문 내역 조회
    • 주문 취소
  • 예제를 단순화 하기 위해 다음 기능은 구현X
  • 로그인과 권한 관리X
  • 파라미터 검증과 예외 처리X
  • 상품은 도서만 사용
  • 카테고리는 사용X
  • 배송 정보는 사용X

애플리케이션 아키텍처

Untitled

  • 계층형 구조 사용
    • controller, web : 웹 계층(컨트롤러 리포지토리에 바로 접근 가능)
    • service : 비즈니스 로직, 트랜잭션 처리
    • repository : JPA를 직접 사용하는 계층, 엔티티 매니저 사용
    • domain : 엔티티가 모여있는 계층, 모든 계층에서 사용
  • 패키지 구조
    • domain
    • exception
    • repository
    • service
    • web

개발 순서: 서비스, 리포지토리 계층을 개발하고, 테스트 케이스를 작성해서 검증, 마지막에 웹 계층 적용

Clone this wiki locally