[Inflearn] 실전! 스프링 부트와 JPA 활용1 - 웹 어플리케이션 개발
1. setter을 남발하지 말 것
setter로 인해 변경되는 부분이 많아지면 이후 유지보수에 어렵다.
2. 모든 연관관계는 지연로딩(LAZY Loading)으로
즉시로딩(EAGER Loading)은 예측이 어렵고 예상치 못한 SQL이 실행될 수 있다(JPQL의 N+1 문제). 연관된 엔티티를 조회해야 한다면 fetch join이나 엔티티 그래프 기능을 이용한다. XtoOne(OneToOne, ManyToOne)은 기본이 즉시로딩임으로 직접 지연로딩 설정해야 한다.
3. 컬렉션은 필드에서 바로 초기화하는 것이 안전
컬렉션은 필드 레벨에서 생성하고 초기화하는 것이 null 문제에 더 안전하다.
1) lombok 이용 (권장)
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
변경할 일이 없기 때문에 final로 선언한다. 컴파일 시점에 memberRepository를 설정하지 않는 오류 체크 가능하다.
2) 필드 직접 주입
@Autowired
public void MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
생성자가 하나일 경우 @Autowired 생략 가능하다.
3) 생성자 주입
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
변경 불가능한 안전한 객체 생성이 가능하기 때문에 생성자 주입 방식을 권장한다.
도메인 모델 패턴
엔티티에 비즈니스 로직을 구현하고 서비스 계층은 단순히 엔티티에 필요한 요청을 위임하는 것으로 엔티티가 비즈니스 로직을 가지고 있는 형태이다.
객체지향의 특성 적극 활용하는 패턴이다.
트랜잭션 스크립트 패턴
엔티티에는 비지니스 로직이 거의 없고 서비스 게층에서 대부분의 비즈니스 로직을 처리하는 것이다.
→ 상황에 맞춰 사용
준영속 엔티티란 영속성 컨텍스트가 더는 관리하지 않는 엔티티로 엔티티 수정하는 방법에는 변경감지와 병합이 있다.
변경감지
@Transactional
void update(Item itemParam) {
Item findItem = em.find(Item.class, itemParam.getId());
findItem.setPrice(itemParam.getPrice());
}
파라미터로 넘어온 준영속 엔티티의 아이디로 트랜젝션 안에서 다시 영속성 컨텍스트에서 해당 엔티티 조회
트랜잭션 커밋 시점에 변경 감지(Dirty Checking)가 동작하여 변경할 데이터에 대한 데이터베이스에 UPDATE SQL 실행
병합
@Transactional
void update(Item itemParam) {
Item mergeItem = em.merge(item);
}
1) merge 실행
2) 파라미터로 넘어온 준영속 엔티티의 식별자로 1차 캐시 조회, 1차 캐시에 없을 경우 데이터베이스 조회
3) 2번을 통해 조회한 영속 엔티티에 준영속 엔티티(파라미터)의 값으로 교체(모든 값을 밀어 넣음)
4) 영속상태의 엔티티 반환
문제점으로는 파라미터의 모든 값을 받아 그 값으로 교체함으로 원하는 값만 수정하지 못한다는 점이 있다. 또한 데이터가 없을 시 null로 업데이트 하게된다.
엔티티를 변경할 때는 항상 '변경감지' 이용할 것
- 서비스 계층에 식별자와 변경할 데이터 명확히 전달할 것(파라미터나 DTO)
- 트랜잭션이 있는 서비스 계층에서 영속 상태의 엔티티를 조회하고 엔티티의 데이터를 직접 변경
[SPRING] JPA 활용2 | API 개발과 성능 최적화(2) (0) | 2021.04.21 |
---|---|
[SPRING] JPA 활용2 | API 개발과 성능 최적화(1) (0) | 2021.04.20 |
[SPRING] JPA 프로그래밍 기본 | 객체지향 쿼리 언어 (0) | 2021.04.08 |
[SPRING] JPA 프로그래밍 기본 | 값 타입 (0) | 2021.04.08 |
[SPRING] JPA 프로그래밍 기본 | 프록시와 지연로딩 (0) | 2021.03.11 |
댓글 영역