package study.querydsl.repository;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import study.querydsl.entity.Member;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Optional;
import static study.querydsl.entity.QMember.member;
@Repository
@RequiredArgsConstructor
public class MemberJpaRepository {
public final EntityManager em;
private final JPAQueryFactory queryFactory;
public void save(Member member) {
em.persist(member);
}
public Optional<Member> findById(Long id) {
Member member = em.find(Member.class, id);
return Optional.ofNullable(member);
}
public List<Member> findAll() {
return em.createQuery("select m from Member m", Member.class)
.getResultList();
}
public List<Member> findAll_Querydsl() {
return queryFactory
.selectFrom(member)
.fetch();
}
public List<Member> findByUsername(String username) {
return em.createQuery("select m from Member m where m.username = :username", Member.class)
.setParameter("username", username)
.getResultList();
}
public List<Member> findByUsername_Querydsl(String username) {
return queryFactory
.selectFrom(member)
.where(member.username.eq(username))
.fetch();
}
}
JPQL과 Querydsl를 사용하여 2가지 버전으로 메소드를 구현하였다.
JPQL은 파라미터를 바인딩할때 setParameter()를 사용해야하지만
Querydsl은 where() 조건안에서 eq()와 함께 사용해줘서 더욱 편리하다.
package study.querydsl.repository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import study.querydsl.entity.Member;
import javax.persistence.EntityManager;
import java.util.List;
import static org.assertj.core.api.Assertions.*;
@SpringBootTest
@Transactional
class MemberJpaRepositoryTest {
@Autowired EntityManager em;
@Autowired MemberJpaRepository memberJpaRepository;
@Test
public void basicTest() {
Member member = new Member("member1", 10);
memberJpaRepository.save(member);
Member findMember = memberJpaRepository.findById(member.getId()).get();
assertThat(member).isEqualTo(findMember);
List<Member> all = memberJpaRepository.findAll();
assertThat(all).containsExactly(findMember);
List<Member> byUsername = memberJpaRepository.findByUsername(member.getUsername());
assertThat(byUsername).containsExactly(member);
}
@Test
public void basicTest_Querydsl() {
Member member = new Member("member1", 10);
memberJpaRepository.save(member);
List<Member> findMember = memberJpaRepository.findAll_Querydsl();
assertThat(findMember).containsExactly(member);
List<Member> byUsernameQuerydsl = memberJpaRepository.findByUsername_Querydsl(member.getUsername());
assertThat(byUsernameQuerydsl).containsExactly(member);
}
}
QueryFactory와 EntityManager를 사용하려면 아래와 같이 생성자를 주입해줘야 한다.
@Repository
public class MemberJpaRepository {
public final EntityManager em;
private final JPAQueryFactory queryFactory;
public MemberJpaRepository(EntityManager em) {
this.em = em;
this.queryFactory = new JPAQueryFactory(em);
}
}
하지만 이런식으로 하기보다는 편리하게 하는 방법이 있다.
package study.querydsl;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import javax.persistence.EntityManager;
@SpringBootApplication
public class QuerydslApplication {
public static void main(String[] args) {
SpringApplication.run(QuerydslApplication.class, args);
}
@Bean
JPAQueryFactory jpaQueryFactory(EntityManager em) {
return new JPAQueryFactory(em);
}
}
SpringBootApplication에서 @Bean으로 주입하면 편리하다.
@Repository
@RequiredArgsConstructor
public class MemberJpaRepository {
public final EntityManager em;
private final JPAQueryFactory queryFactory;
}
@RequiredArgsConstructor를 사용하여 생성자를 생성할 수 있다.