1.엔티티에는 가급적 Setter를 사용하지 말자(강조)
-Setter가 모두 열려있으면 변경 포인트가 너무 많아서,
특정 엔티티하나가 어디서 수정된 것인지 알기가어렵다. 그래서 유지보수가 어렵다.
-Setter를 안열면 어떻게 알 수 있는지는에 대해서는 추후 웹어플리케이션 개발강의에서 비즈니스 메서드를 등록하면서
코드를 가지고 보여줄 예정!
-예제에서는 Setter를 열어둔 이유는 그때 마다 보여줄 수 있는 실습내용이 있기에 열어둠!
나중에 리펙토링으로 Setter 제거할 예정!
실무에서는 가급적이면 setter를 열지말자!
2.모든 연관관계는 지연로딩으로 설정!
(엄청중요하다!, 수많은 장애를 극복할 수 있다!, 외워야 한다.)
a.즉시로딩을 절대로 사용하지 말자
-즉시로딩(EAGER)은 어떤 종류의 SQL이 실행될지 추측하기 어렵다.
-JPQL 실행시에는 N+1 이슈가 자주 발생할 수 있다.
-최악의 경우엔 하나 연관된 데이터(디비)를 전부 다 데리고 오기 때문에
개발시에 어려워진다.
*즉시로딩설정이 되있을시에 네이처로 전부 변경하고 튜닝을 할 수 있다.
그래서
-연관관계는 꼭 지연로딩(LAZY)으로 설정해야 한다.
-즉시로딩이 아니어도 원하는 데이터를 실시간으로 선택하여 가져올 수 있는 방법이 있다.
연관된 엔티티를 함께 DB에서 조회해야 할 경우는 fetch join/엔티티 그래프 기능 사용권장
*즉시로딩이 있고 지연로딩이 있다.
즉시로딩
-멤버를 조회할 때 연관된 필요한 주문을 다른 조회한다.
로딩하는 시점(멤버를 조회)에 다른 연관된 주문들도 로딩하겠다는 의미
*지연로딩의 장점
order를 조회할 때 member를 이렇게 설정해놓을 시에
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "member_id")
private Member member;
-order를 조회할 때 member 조인을 해서 쿼리 한번에 같이 조회가능하도록 한다.
한건 조회할 때는 em.find()인 경우에만 가능하다.
3. 즉시로딩일 때에는 특히 JPQL을 실행할 때 N+1 문제가 자주 발생한다.
즉시로딩의 문제 예시
예제1
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "member_id")
private Member member;
설명
JPQL이 제공하는 쿼리를 가지고 주문조회를 할 경우
JPQL select o From order o;
-> SQL select * from order n + 1 ( SQL문 그대로 번역을 하게 된다.)
-그러면 sql이 갈 때에는 주문 100개 조회하여 데이터 100개를 가져오지만,
-이때 member는 (fetch = FetchType.EAGER)를 본다.
-그래서 데이터를 100개 100번을 가져오기 위해 단방 쿼리가 100개를 보내게 된다.
이것을 n+1 문제라고 한다.
왜 n+1이냐
-첫 번째 주문조회를 위해 쿼리를 날려서 가져온 쿼리결과가 100개이면
SQL select * from order n + 1에서 n을 100개로 치환화시키기 때문이고,
그만큼 멤버(member)를 가져오기 위한 쿼리를 100개 보내게 된다.
4.@XToOne(OneToOne, ManyToOne)..x시리즈 관계는 기본이 즉시로딩이므로
직접 지연로딩으로 설정해야 한다.
예)
@ManyToOne
@JoinColumn(name = "member_id")
private Member memebr;
@OneToMany(mappedBy = "order")
private List<OrderItem> orderItems = new ArrayList<>();
설명
@ManyToOne의 기본패치는 FetchType fetch() default EAGER;
- 얼핏 볼때에는 이것이 맞는 것 같다.
@OneToMany의 기본패치는 FetchType fetch() default LAZY;
-@OneToMany는 LAZY이기 때문에 따로 설정을 해줄 필요가 없지만
@ManyToOne 디폴트가 fetch = FetchType.EAGER이므로
직접 따로 (fetch = FetchType.LAZY)로 설정을 해주어야 한다.
*@OneToOne도 기본패치 디폴트가 fetch = FetchType.EAGER이다.
-설정을 해주지 않으면 연관된 하나 데이터를 가져오기 위해 쿼리 1개를 보내는 것 같지만
연관된 데이터 조회를 위해 쿼리를 엄청나게 많이 보내게 되므로 일일이 찾아서 LAZY로 설정을 해주어야 한다.
*쿼리 종류 및 의미를 이해해야 한다.(내가부족한 것)
5. 실습-@ManyToOne을 찾아서 지연로딩(LAZY)로 설정을 해주자
a.fetch 설정하는 사진
b.그리고 나머지 @ManyToOne을 찾아서 바꿔준다.
-jpabook.jpashop에서 ctrl + shift + f를 하면 다음과 같은 화면이 나온다.
c.@OneToOne도 LAZY 지연로딩으로 변경해준다.
d.static import(좀더 깔끔하게 외관상 LAZY로 보여지게 하는 방법)
-FetchType위에서 alt + enter를 타입하면 위와 같이 변경이 된다.
*엔티티개발을 하면서 중간중간에 내가 작성한대로 생성이 되었는지 확인을 해라
*실행툴 안에 나오는 메시지에서 생성된 테이블 생성코드 그대로 작성해도 되는가 - 안된다.
예)
create table orders (
order_id bigint not null,
order_date timestamp,
status varchar(255),
delivery_id bigint,
member_id bigint,
primary key (order_id)
);
-디테일하게 수정해야 할 것들이 있다. 수정하고 정리해서 사용한다.
'신입개발자로 취업하기까지 > JPA쇼핑몰기능구축' 카테고리의 다른 글
20200525 엔티티설계 보충설명 (0) | 2020.06.08 |
---|---|
20200524 엔티티설계 및 개발시 주의점_2 (0) | 2020.06.08 |
20200519 도메인분석설계_엔티티클래스 개발 1-6 (0) | 2020.06.07 |
20200518 도메인분석설계_엔티티클래스 개발 1-5 (0) | 2020.06.07 |
20200517 도메인분석설계_엔티티클래스 개발 1-4 (0) | 2020.06.07 |