2 분 소요

인프런 실전! Querydsl 강의 내용 정리


순수 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이 초기 세팅만 좀 많이 어렵지, 세팅만 되면… 진짜 편리하다.

태그:

카테고리:

업데이트:

댓글남기기