JPA에서 Lazy Loading과 Eager Loading의 차이점과 각각의 장단점
차이점
JPA는 연관관계가 설정된 엔티티의 정보를 바로 가져올지, 필요할 때 가져올지 정하는데 그 방법을 Fetch Type이라고 합니다. Fetch Type의 2가지 종류가 Lazy Loading과 Eager Loading입니다.
레이지 로딩은 지연로딩으로 필요한 시점에 정보를 가져옵니다.
이걸 로딩은 즉시로딩으로 조회할 때 연관된 모든 엔티티의 정보를 즉시 가져옵니다.
그들의 장단점
으로는 우선 eager loading은 데이터를 한번에 가져오기 때문에 데이터 접근시 추가적인 데이터베이스 쿼리가 발생하지 않아 네트워크 지연을 줄일 수 있습니다. 하지만 단점으로는 불필요한 데이터를 미리 로딩하기 때문에 메모리 사용량이 증가해 메모리 부담이 커질 수 있고 데이터 양이 많을 경우 초기 로딩시간이 길어질 수 있다.
그리고 lazy loading의 장점은 필요할 때만 데이터를 가져오기 때문에 불필요한 데이터를 미리 로딩하지 않아 데이터 사용량을 줄일 수 있습니다. 하지만 연관된 엔티티에 접근할 때마다 추가 쿼리가 발생하여 N+1 문제를 야기할 수 있다. 그리고 추가적인 쿼리가 많아지면 응답시간이 길어지고 비용이 증가해서 성능 저하가 발생할 수 있습니다.
그럼 어떤 때에 lazy loading을 사용하고 어떤 때에 eager loading을 쓰나요?
lazy loading과 eager loading을 선택할 때는 어플리케이션의 특성과 요구사항을 고려해야 합니다. 예를 들어, 데이터 접근 빈도가 낮고 메모리 사용량을 줄이고 싶은 페이징이나 무한 스크롤이 있는경우 lazy loading을 사용하여 현재 부분만 데이터를 로드하여 효율적으로 메모리를 사용할 수 있습니다.
반면에 데이터 접근 빈도가 높은 대시보드 같이 여러연관된 데이터가 모두 필요한 경우 eager loading을 선택하는 것이 좋습니다.
JPA 란?
JPA(Java Persistence API)는 자바 객체를 데이터베이스 테이블과 쉽게 연결할 수 있도록 도와주는 표준 인터페이스입니다. 복잡한 SQL 없이 자바 코드로 데이터베이스 작업을 할 수 있게 해주는 ORM(Object-Relational Mapping) 기술이다.
ORM 이란?
객체와 데이터베이스를 매핑해주는 도구입니다. SQL 작업을 줄여주기 위해 등장했고 데이터베이스 연결 과정을 자동으로 처리해줍니다.
JPA에서 N+1 문제를 해결하기 위한 방법
N+1 문제란?
펫치타입이 lazy loading일 때 나오는 문제이며, 하나의 메인 쿼리를 통해 특정 데이터(N)를 조회할 때, 각 데이터와 연관된 정보를 추가로 조회하기 위해 또 다른 쿼리를 반복적으로 실행하여 총 N+1개의 쿼리가 발생하는 문제입니다. N+1문제가 발생하면 쿼리가 배수적으로 증가하면서 데이터베이스에 큰 부담이 발생하게 되고 장애 요인이 될 수 있습니다.
해결방법으로는
JPQL로 직접 Fetch Join 쿼리문을 작성하는 방법
Fetch Join은 실제 SQL에 있는 Join의 종류가 아니며, JPQL에서 성능 최적화를 위해 제공하는 Join 기능입니다. 연관된 엔티티나 컬렉션을 한 번에 같이 조회할 수 있도록 지원합니다.
배치 사이즈 설정
batch size를 사용하여 한번에 지연로딩으로 가져올 데이터의 양을 조절가능하다.
batch size를 사용하여 IN 쿼리를 통해 해결하는데
이때 IN 절에 한번에 들어가는 크기를 BatchSize의 옵션으로 설정할 수 있습니다.
@EntityGraph 어노테이션 사용
특정메서드에서만 연관된 엔티티를 한 번의 쿼리로 조회하는 방법이 있습니다.
eager loading 으로 변경
lazy loading을 eagerloading으로 변경하여 연관된 데이터를 한번의 쿼리로 모두 가져옵니다.
하지만 이방법은 모든 연관데이터를 다 가져오므로 불필요한 데이터가 로드될 가능성이 있어 성능에 영향을 줄수 있습니다. 따라서 필요한 경우 선택적으로 사용해야 합니다.
이런 방법들을 통해 N+1 문제를 해결할 수 있습니다.
JPQL이란?
JPQL(Java Persistence Query Language)은 JPA에서 사용하는 객체 지향 쿼리 언어입니다. JPQL은 데이터베이스 테이블이 아닌 JPA 엔티티 객체를 대상으로 하여 데이터를 조회하거나 조작할 수 있도록 설계되었습니다. 이는 SQL과 유사하지만, SQL이 데이터베이스 테이블을 직접 대상으로 하는 반면 JPQL은 엔티티 클래스와 그 필드를 대상으로 쿼리를 작성합니다.
하이버네이트
자바에서 가장 널리 사용되는 ORM 프레임워크입니다
JPA의 구현체로 JPA 인터페이스를 구현하고 내부적으로 JDBC API를 사용한다.
단위 테스트와 통합 테스트의 차이점과 각각의 장단점
단위테스트란 ?
가장 작은 단위의 테스트 방식이며 메서드 단위로 테스트를 수행하고, 코드의 특정 기능이 예상대로 작동하는지를 확인하는 테스트
통합 테스트란 ?
여러 모듈을 함께 테스트하며 여러 모듈이나 시스템이 함께 작동하는지를 검증하는 테스트
단위 테스트가 개별 모듈의 기능을 검증하는 것에 초점을 맞춘다면, 통합 테스트는 이들 모듈이 서로 통합되어 상호작용할 때 발생할 수 있는 문제를 찾아내고 해결하는 데 중점을 둡니다.
각각의 장단점
으로는 우선 단위테스트는 빠르게 실행되고, 문제 발생 시 어느 부분이 잘 못 되었는지 빠르고 정확하게 확인할 수 있습니다. 또, 코드 수정후 즉시 테스트 할 수 있어 문제를 조기에 발견가능하다는 장점이 있습니다. 단점은 작은 단위로만 테스트하기 때문에 시스템 전체의 동작을 보장하지 않습니다.
그리고 통합테스트는 실제 환경과 유사한 조건에서 테스트하여 현실적인 테스트 결과를 제공하고, 단위 테스트로는 발견하기 어려운 모듈 간 상호작용 문제를 찾아낼 수 있습니다.
단점으로는 여러 모듈을 포함하여 테스트하므로 단위 테스트보다 실행 속도가 느리고, 문제가 발생했을 때, 원인을 찾기 어렵습니다.
F.I.R.S.T 원칙 -> (참고만 하자)
- Fast : 단위 테스트는 빨라야 한다. (가장 중요~)
- Independent : 단위 테스트는 각각의 테스트가 연관되지 않고, 고립되어야 한다. 즉 독립적이어야 한다.
- Repeatable : 단위테스트는 반복 가능해야한다. 반복적으로 시행해도 결과는 같아야 한다.
- Self-validating : 자체적으로 테스트 결과가 도출되야한다. (개발자가 print 찍어서 비교하는게 아니고 자동으로 수행되며 성공/실패 의 결과가 나오는 것)
- Timely : 단위 테스트는 실제 코드보다 먼저 구현해야한다. (TDD일 경우에만 해당)
QueryDSL을 사용하여 복잡한 동적 쿼리를 작성하는 방법
QueryDSL이란?
QueryDSL은 자바 기반의 타입 안전한 쿼리 작성 도구로, SQL이나 JPQL 쿼리를 자바 코드로 작성할 수 있게 도와주는 라이브러리입니다.
QueryDSL을 사용하여 복잡한 동적 쿼리를 작성하는 방법은?
동적 쿼리를 작성하는 과정은 크게 3단계로 나눌 수 있습니다.
첫째, Q타입 클래스 생성을 통해 엔터티의 필드를 참조하고,
둘째, 동적으로 조건을 추가하기 위해 booleanBuilder 객체를 생성,
셋째, JPAQueryFactory를 사용해 쿼리를 실행합니다.
이를 통해 동적으로 여러 조건을 처리할 수 있습니다.
QueryDSL을 사용하는 이유?
따라서 QueryDSL을 통해 동적 쿼리를 작성할 때 코드 가독성, 타입 안전성, 그리고 유지보수 측면에서 장점이 있습니다.
JPA Repository에 메소드로 조건을 여러개 설정하는 경우 이름 길어지는 단점이 있는데 그걸 QueryDSL로 변경하면 가독성이 좋아지고 SQL문을 작성하는것과 유사하게 쉽게 작성할 수 있어 QueryDSL을 사용한다고 생각합니다.
'java 배우기 > TIL' 카테고리의 다른 글
| 컨트롤러 테스트코드 수정하기 (0) | 2024.10.10 |
|---|---|
| 기술 면접 준비하기-2 (0) | 2024.10.10 |
| N+1 문제 해결해보기 (0) | 2024.10.03 |
| date 타입 불일치로 인한 에러 (2) | 2024.10.03 |
| 포크해온 코드 분리하기 (0) | 2024.10.02 |