먼저 JPQL 과 어떤 차이가 있는지 설명하도록 하겠습니다.
@SpringBootTest
@Transactional
public class QuerydslBasicTest {
@PersistenceContext
EntityManager em;
@BeforeEach
void setUp() {
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);
}
@Test
void startJPQL() {
//member1을 찾아라.
String qlString = "select m from Member m where m.username = :username";
Member findMember = em.createQuery(qlString, Member.class)
.setParameter("username", "member1")
.getSingleResult();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
@Test
void startQuerydsl() {
JPAQueryFactory queryFactory = new JPAQueryFactory(em); //...1
QMember m = QMember.member; //...2
//member1을 찾아라.
Member findMember = queryFactory
.select(m)
.from(m)
.where(m.username.eq("member1"))
.fetchOne();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
}
QMember qMember = QMember.member
로 씁니다. 그래서 별칭은 중요하지 않습니다.JPQL 은 파라미터 바인딩을 문자열로 직접했지만 Querydsl 은 파라미터 바인딩을 자동 처리합니다.
JPQL 은 파라미터 바인딩 뿐만아니라 쿼리 자체를 문자열로 처리하기 때문에 만약 오타가 발생한다면 문제가 생긴 쿼리를 호출할 때 문제를 알 수 있습니다. 단순 문자열이라 실행이 되기 때문이죠.
하지만 Querydsl 은 컴파일 시점에 오류를 잡아줍니다. 쿼리를 자바 코드로 작성하기 대문이죠.
추가적으로 Querydsl 은 코드 어시스턴스가 어마어마해서 쉽게 작성할 수 있습니다.
@SpringBootTest
@Transactional
public class QuerydslBasicTest {
@PersistenceContext
EntityManager em;
JPAQueryFactory queryFactory; //...1
@BeforeEach
void setUp() {
queryFactory = new JPAQueryFactory(em); //...1
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);
}
@Test
void startJPQL() {
//member1을 찾아라.
String qlString = "select m from Member m where m.username = :username";
Member findMember = em.createQuery(qlString, Member.class)
.setParameter("username", "member1")
.getSingleResult();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
@Test
void startQuerydsl() {
QMember m = QMember.member; //...2
//member1을 찾아라.
Member findMember = queryFactory
.select(m)
.from(m)
.where(m.username.eq("member1"))
.fetchOne();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
}
JPAQueryFactory를 필드로 빼셔도 상관 없습니다.