Querydsl - 실무 활용 - 순수 JPA 리포지토리와 Querydsl
인프런 실전! Querydsl 강의 내용 정리
- 순수 JPA 리포지토리와 Querydsl
- 동적 쿼리 Builder 적용
- 동적 쿼리 Where 적용
- 조회 API 컨트롤러 개발
순수 JPA 리포지토리와 Querydsl
순수 JPA 리포지토리

다음과 같이 패키지와 파일을 만들어 줬다.
그리고 기본적인 save, findById, findAll, findByUsername 메서드를 만들어 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Repository
public class MemberJpaRepository {
private final EntityManager em;
private final JPAQueryFactory queryFactory;
public MemberJpaRepository(EntityManager em) {
this.em = em;
this.queryFactory = new JPAQueryFactory(em);
}
public void save(Member member) {
em.persist(member);
}
public Optional<Member> findById(Long id) {
Member findMember = em.find(Member.class, id);
return Optional.ofNullable(findMember);
}
public List<Member> findAll() {
return em.createQuery("select m from Member m", Member.class)
.getResultList();
}
public List<Member> findByUsername(String username) {
return em.createQuery("select m from Member m where m.username = :username", Member.class)
.setParameter("username", username)
.getResultList();
}
}
평범하게 JPQL로 만든 순수 JPA 리포지토리다.
queryDsl 도 여기서 사용할 거기 때문에
1
2
3
4
5
6
7
private final EntityManager em;
private final JPAQueryFactory queryFactory;
public MemberJpaRepository(EntityManager em) {
this.em = em;
this.queryFactory = new JPAQueryFactory(em);
}
다음과 같이 생성자를 만들어 줬다.
참고로 QueryDsl 은 Bean으로 등록 해서 사용해도 된다.
그럼 Main 클래스에서
1
2
3
4
@Bean
JPAQueryFactory jpaQueryFactory(EntityManager em) {
return new JPAQueryFactory(em);
}
다음과 같이 등록하고
1
2
3
4
5
6
7
private final EntityManager em;
private final JPAQueryFactory queryFactory;
public MemberJpaRepository(EntityManager em, JPAQueryFactory queryFactory) {
this.em = em;
this.queryFactory = queryFactory;
}
다음과 같이 사용하면 된다. 동시성 문제 없다.
또 롬복 사용해서 @NoArgsConstructor 사용할 수도 있다.
그런데 단점이 의존성을 2개 주입해야 하기 때문에 테스트 코드가 조금 더 복잡해 지긴 할 것 같다.
난 처음 방식을 쓰겠다 일단.
이제 만든 걸 테스트 해 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Test
public void basicTest() throws Exception {
//given
Member member = new Member("member1", 10);
memberJpaRepository.save(member);
//when
Member findMember = memberJpaRepository.findById(member.getId()).get();
//then
assertThat(findMember).isEqualTo(member);
List<Member> result1 = memberJpaRepository.findAll();
assertThat(result1).containsExactly(member);
List<Member> result2 = memberJpaRepository.findByUsername("member1");
assertThat(result2).containsExactly(member);
}
뭐 간단한 테스트 이다.

통과도 잘 됬다.
이제 QueryDsl을 사용해서 findAll, findByUsername 메서드를 다시 만들어 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
public List<Member> findAll_Querydsl() {
return queryFactory
.selectFrom(member)
.fetch();
}
public List<Member> findByUsername_Querydsl(String username) {
return queryFactory
.selectFrom(member)
.where(member.username.eq(username))
.fetch();
}
매우 깔끔해 졌다.
또 장점은 이거다.

딸깍 메타가 가능하다…
그에 반해 원래 순수 JPA는 어떤지 보자.

저기서 오타 나도 모른다.. ㅋㅋ
테스트 해보자.
1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void basicQuerydslTest() throws Exception {
Member member = new Member("member1", 10);
memberJpaRepository.save(member);
List<Member> result1 = memberJpaRepository.findAll_Querydsl();
assertThat(result1).containsExactly(member);
List<Member> result2 = memberJpaRepository.findByUsername_Querydsl("member1");
assertThat(result2).containsExactly(member);
}
간단하게 member를 가지고 있나 체크해 봤다.

테스트도 잘 통과가 된 걸 볼 수 있다.
아무튼 QueryDsl이 초기 세팅만 좀 많이 어렵지, 세팅만 되면… 진짜 편리하다.
댓글남기기