반응형
해당 글은 김영한 님의 querydsl을 수강하며 정리하려고 적는 포스팅입니다.
지금 소개하는 기능은 제약이 커서 복잡한 실무 환경에 사용하기에는 많이 부족하다.
그래도 spring data에서 제공하는 기능이므로 간단히 소개하고, 왜 부족한지 설명한다.
💡 인터페이스 지원 - QuerydslPredicateExecutor
QuerydslPredicateExecutor 인터페이스
public interface QuerydslPredicateExecutor<T> {
Optional<T> findById(Predicate predicate);
Iterable<T> findAll(Predicate predicate);
long count(Predicate predicate);
boolean exists(Predicate predicate);
// … more functionality omitted.
}
리포지토리에 적용
- 앞서 포스팅한 MemberRepository에 QuerydslPredicateExecutor <T>를 추가해 주었다.
public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom, QuerydslPredicateExecutor<Member> {
List<Member> findByUsername(String username);
}
테스트
package study.querydsl.repository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import study.querydsl.dto.MemberSearchCondition;
import study.querydsl.dto.MemberTeamDto;
import study.querydsl.entity.Member;
import study.querydsl.entity.QMember;
import study.querydsl.entity.Team;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest
@Transactional
class MemberRepositoryTest {
@PersistenceContext
EntityManager em;
@Autowired
MemberRepository memberRepository;
@Test
public void querydslPredicateExecutorTest() {
Team teamA = new Team("teamA");
Team teamB = new Team("teamB");
em.persist(teamA);
em.persist(teamB);
Member member1 = new Member("member1", 10, teamA);
Member member2 = new Member("member2", 20, teamA);
Member member3 = new Member("member3", 30, teamB);
Member member4 = new Member("member4", 40, teamB);
em.persist(member1);
em.persist(member2);
em.persist(member3);
em.persist(member4);
QMember member = QMember.member;
Iterable<Member> result = memberRepository.findAll(member.age.between(10, 40).and(member.username.eq("member1")));
for (Member findMember : result) {
System.out.println("findMember = " + findMember);
}
}
}
---------------------------------------------------------------------------------------
2023-01-18T15:23:48.108+09:00 DEBUG 14500 --- [ main] org.hibernate.SQL :
/* select
member1
from
Member member1
where
member1.age between ?1 and ?2
and member1.username = ?3 */ select
m1_0.member_id,
m1_0.age,
m1_0.team_id,
m1_0.username
from
member m1_0
where
m1_0.age between ? and ?
and m1_0.username=?
findMember = Member(id=1, username=member1, age=10)
한계점
- 간단한 곳에서 사용하는 것은 가능하다.
- 조인이 불가능 하다. (묵시적 조인은 가능하지만 left join이 불가능하다.)
- 클라이언트가 Querydsl에 의존해야 한다.
- service와 controller 등이 Querydsl이라는 구현 기술에 의존해야 하므로 좋지 않다.
- repository를 만드는 이유는 하부에 querydsl과 같은 구체화된 기술을 숨기는 목적이다.
- 만약에 querydsl이나 다른 기술을 변경하려고 할 때, repository만 변경하면 되는데 service와 controller가 의존하게 되면 모든 게 변경되어야 하기 때문에 좋지 않은 것이다.
- 순수한 DTO 같은 class를 넘기는 것이 아니라 querydsl과 연관된 객체를 만들어 넘겨야 한다는 것이다.
- 복잡한 실무환경에서 사용하기에는 한계가 명확하다.
참고: QuerydslPredicateExecutor 는 Pagable, Sort를 모두 지원하고 정상 동작한다
💡 참고 : Query Web 지원
- 사용하지 않는 것 권장 (득보다 실이 크다.)
- 공식 URL : Spring Data JPA - Reference Documentation
한계점
- 단순한 조건만 가능
- 조건을 커스텀하는 기능이 복잡하고 명시적이지 않다.
- 컨트롤러가 Querydsl에 의존한다.
- 복잡한 실무환경에서 사용하기에 한계가 명확하다.
반응형
'Java' 카테고리의 다른 글
함수형 인터페이스 - java.util.function 패키지 (0) | 2023.02.01 |
---|---|
[Java] 람다식과 작성 방법 - 함수형 인터페이스 사용 (매개변수, 반환타입) (0) | 2023.01.31 |
Querydsl 페이징 연동 및 최적화 - Querydsl fetchResults() , fetchCount() Deprecated(향후 미지원) (0) | 2023.01.18 |
순수 JPA를 Spring data JPA로 변경하는 법 (0) | 2023.01.18 |
[spring] 환경에 따른 설정 파일 나누기 - application.yml/@Profile (0) | 2023.01.17 |