@Repository
public class MemberJpaRepository {
private final EntityManager em;
private final JPAQueryFactory queryFactory;
public MemberJpaRepository(EntityManager em) {
this.em = em;
this.queryFactory = new JPAQueryFactory(em);
}
Querydsl을 사용하려면 JPAQueryFactory가 있어야한다. 파라미터로는 EntityManage를 받는다.
@Test
void startQuerydsl() {
final JPAQueryFactory queryFactory = new JPAQueryFactory(em);
final QMember m = new QMember("m");
final Member findMember = queryFactory
.select(m)
.from(m)
.where(m.username.eq("member1"))
.fetchOne();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
이게 querydsl방식이다. QMember()에 예시로 m이라는 별칭같은걸 넣어주었다. EntityManager를 JPAQueryFactoryd에 넣고 거기서 셀렉트같은 쿼리를 아주 간편하게 뽑아낼수 있다.
where절에 보면 m.username.eq()는 자동으로 jdbc에 있는 preparedstatement로 파라미터를 자동으로 바인딩을 한다.
그래서 sql인젝션 공격을 방어할수있다. 그리고 그냥 sql문을 작성했을때 오타로 인한 오류가 날 수 있다. 그럼 실제 어플리케이션이 돌아가는 시점에 확인 할수있게 된다. 하지만 querydsl은 오타가 발생하면 바로 컴파일오류가 나기 때문에 실행전에 오류를 알수있다.
장점은 파라미터 바인딩을 자동으로 해주고 오타로 인한 오류는 컴파일 오류로 확인할수있다는 점.
@Test
void search() {
final Member findMember = queryFactory
.selectFrom(QMember.member)
.where(QMember.member.username.eq("member1")
.and(QMember.member.age.between(10, 30)))
.fetchOne();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
@Test
void searchAndParam() {
final Member findMember = queryFactory
.selectFrom(member)
.where(
member.username.eq("member1"),
member.age.eq(10)
)
.fetchOne();
assertThat(findMember.getUsername()).isEqualTo("member1");
}
그리고 여러 동적쿼리 지원. searchAndParam()에서 where절에 쉼표는 and절로 인식된다. 결과를 보면
member0_.username=?
and member0_.age=?
이런식으로 and절로 표현됨.
member는 QMember.member;를 static import를 한것.
페이징 처리
@Test
void paging1() {
final List<Member> result = queryFactory
.selectFrom(member)
.orderBy(member.username.desc())
.offset(1)
.limit(2)
.fetch();
assertThat(result.size()).isEqualTo(2);
}
@Test
void paging2() {
final QueryResults<Member> queryResults = queryFactory
.selectFrom(member)
.orderBy(member.username.desc())
.offset(1)
.limit(2)
.fetchResults();
assertThat(queryResults.getTotal()).isEqualTo(4);
assertThat(queryResults.getLimit()).isEqualTo(2);
assertThat(queryResults.getOffset()).isEqualTo(1);
assertThat(queryResults.getResults().size()).isEqualTo(2);
}
'QueryDSL' 카테고리의 다른 글
querydsl 설정 (0) | 2023.05.31 |
---|---|
벌크연산시 우선순위 (0) | 2022.10.31 |
QueryDSL설정 (0) | 2022.10.30 |