엔티티 클래스 설계
위 회원 엔티티 관계도를 보고 VO 생성 코드를 만들어 본다.
회원(Member) 엔티티
주문(Order) 엔티티
주문상품(OrderItem)엔티티
주문상태(OrderStatus)
배송(Delivery)엔티티
배송상태(DeliveryStatus)
주소(Address) 값 타입(임베디드 타입)
아이템(Item) 엔티티
아이템 - 책 엔티티
아이템 - 영화 엔티티
아이템 - 앨범 엔티티
카테고리(Category) 엔티티
참고: 이론적으로 Getter, Setter를 모두 제공하지 않고, 꼭 필요한 별도의 메서드를 제공하는게 가장 이상적이다.
하지만 실무에서 엔티티의 데이터는 조회할 일이 너무 많으므로, Getter의 경우 모두 열어두는 것이 편리하다. 하지만, Setter를 호출하면 데이터가 변하기 때문에 Setter를 막 열어두면 엔티티가 어떻게 어디서 왜 바뀌는지 추적하기가 힘들어진다.
그렇기 때문에 엔티티를 변경할때는 Setter 대신 변경 지점이 명확하도록 변경을 위한
비즈니스 메서드를 별도로 제공해야 한다.
엔티티 설계시 주의점
•
엔티티에서는 가급적 Setter를 사용하지 말자.
◦
Setter가 열려있으면 변경 포인트가 너무 많아 유지보수가 어렵다.
•
모든 연관관계는 지연로딩으로 설정
◦
즉시로딩(EAGER)예측이 어렵고, 어떤 SQL이 실행될 지 추적하기 어렵다.
◦
ManyToOne이나 OneToOne과 같은 xxxToOne 매핑은 기본 전략이 EAGER이므로 수동으로 LAZE로 바꾸도록 해야 한다.
◦
특히, JPQL을 실행할 때 N+1 문제가 자주 발생한다.
◦
연관된 엔티티를 함께 DB에서 조회해야 하면, fetch join 또는 엔티티 그래프 기능을 사용한다.
•
컬렉션은 필드에서 초기화 하자.
◦
컬렉션은 필드에서 바로 초기화 하는것이 안전하다.
◦
null 문제에서 안전하다.
◦
하이버네이트는 엔티티를 영속화 할 때, 컬렉션을 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변경한다.
→ 만약 getOrders() 처럼 임의의 메서드에 컬렉션을 잘못 생성하면 하이버네이트 내부 메커니즘에 문제가 발생할 수 있다.
•
테이블 컬럼명 생성 전략
https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#howto-
configure-hibernate-naming-strategy
http://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/
Hibernate_User_Guide.html#naming
◦
하이버네이트 기존 구현: 엔티티의 필드명을 그대로 테이블 명으로 사용(SpringPhysicaNamingStrategy)
◦
스프링 부트 신규 설정(엔티티(필드)→테이블(컬럼))
1.
카멜 케이스 → 언더스코어(userId → user_id)
2.
.(점) → _(언더스코어)
3.
대문자 → 소문자
적용 2단계
1.
논리명 생성: 명시적으로 컬럼, 테이블명을 직접 적지 않으면 ImplictNamingStrategy사용
spring.jpa.hibernate.naming.implict-strategy: 테이블이나, 컬럼명을 명시하지 않을 때 논리명 적용.
2.
물리명 적용:
spring.jpa.hibernate.naming.physical-strategy: 모든 논리명에 적용됨, 실제 테이블에 적용
(username → usernm등으로 회사 규정대로 바꿀 수 있음)
스프링 부트 기본 설정
spring.jpa.hibernate.naming.implicit-strategy:
org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
spring.jpa.hibernate.naminig.physical-strategy:
org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
YAML
복사