[Querydsl] querydsl 학습_2

2020. 8. 28. 19:09개발/DBMS

반응형

[2주차]

 

기본 문법 (구조, 검색, 정렬, 페이징)

 

사전 학습

  • 기본 문법을 배우기 전에 Querydsl 통해 작성 할 수있는 쿼리의 종류에 대해 알아보자.

Querydsl 쿼리 종류

 

Thread Safe as Bean(Singleton)

Use EntityManager(First Caching)

 

Use Entity Class

 

JPAQuery

 

new

 

v

 

v

 

JPAQueryFactory

 

v

 

v

 

v

 

JPASQLQuery

 

new

 

v (No First Caching)

 

Table

 

SQLQuery

 

new

 

DataSource

 

Table

 

SQLQueryFactory

 

v

 

DataSource

 

Table

 

  •   쿼리문을 작성하기 위해서 모두 Q 타입 클래스를 사용

  •   JPAQuery, JPAQueryFactory 클래스를 사용하면 EntityManager를 통해서 질의가 처리되고 이 때 사용하는 쿼리문은 JPQL 사용

  •  SQLQuery, SQLQueryFactory 클래스를 사용하면 JDBC 기술을 사용하여 질의가 처리되고 이 때 사용하는 쿼리문은 SQL를 사용

  • JPASQLQuery 클래스를 사용하면 EntityManager를 통해서 질의가 처리되고 이 때 사용하는 쿼리문은 SQL입니다. 추가적으로 EntityManager를 이용하고 싶을 때 사용

 

기본 문법 (구조, 검색, 정렬, 페이징)

 

 

1. 구조

  • 아래와 같은 실제 쿼리문 기준으로 JPQL, QUERYDSL 와 비교하여 학습을 진행

    • 실제 쿼리문: select * from Member where username = “member1”

import javax.persistence.EntityManager;
import com.querydsl.jpa.impl.JPAQueryFactory;

@Autowired
EntityManager em;

JPAQueryFactory queryFactory;

@Test
@DisplayName("QueryDsl 시작")
void start() {
  queryFactory = new JPAQueryFactory(em);

  //given JPQL
  Member findMember = em
      .createQuery("select m from Member m where m.username = :username", Member.class)
      .setParameter("username", "member1")
      .getSingleResult();
      
  //given querydsl_1
  Member findMember2 = queryFactory
      .selectFrom(member) // select 와 from 한번에도 가능
      .where(member.username.eq("member1")).fetchOne();

  //given querydsl_2
  Member findMember3 = queryFactory
      .select(member)
      .from(member)
      .where(member.username.eq("member1")).fetchOne();

  //when, then JPQL
  assertEquals(findMember.getUsername(), "member1");

  //when, then QueryDsl
  assertEquals(findMember2.getUsername(), "member1");
}

 

구조 문법

문법 기능
.selectFrom(member) select * from Member
.select(member) select *
.from(member) from Member
.where(member.username.eq("member1")) where username = “member1”

 

2_1. 검색 (조건)

  • .where() 안에 내가 찾고 싶은 조건을 추가 할 수 있다.

  • 만약 조건이 여러개 라면???

  • 방법_1. .and() .or() 를 사용하여 연결 한다.

1 .where(member.username.eq("member1").and(member.age.eq(10)));
  • 방법_2.“,” 쉼표를 구분자로 연결 한다. 단, 이 방법 경우 무조건 and 조건이다.

 .where(member.username.eq("member1") , member.age.eq(10))
  • 다양한 조건 질의어

* member.username.eq("member1") // username = 'member1'
* member.username.ne("member1") //username != 'member1'
* member.username.eq("member1").not() // username != 'member1'
*
* member.username.isNotNull() //이름이 is not null
* member.age.in(10, 20) // age in (10,20)
* member.age.notIn(10, 20) // age not in (10, 20)
* member.age.between(10,30) //between 10, 30
*
* member.age.goe(30) // age >= 30
* member.age.gt(30) // age > 30
* member.age.loe(30) // age <= 30
* member.age.lt(30) // age < 30
*
* member.username.like("member%") //like 검색
* member.username.contains("member") // like ‘%member%’ 검색
* member.username.startsWith("member") //like ‘member%’ 검색

 

 

2_2. 검색( 조회)

  • 단 건 조회, 리스트 조회 등 여러가지 방법으로 조회 할 수 있다.

@Test
@DisplayName("검색")
void resultFetch() {
  
  List<Member> f = queryFactory.selectFrom(member).fetch();
  Member fetchOne = queryFactory.selectFrom(member).fetchOne();
  Member fetchFirst = queryFactory.selectFrom(QMember.member).fetchFirst();

  QueryResults<Member> results = queryFactory.selectFrom(member).fetchResults();

  long total = results.getTotal();
  List<Member> content = results.getResults();

  long totalCnt = queryFactory.selectFrom(member).fetchCount();
}

 

 

조회 문법

문법

기능

.fetch()

리스트 조회, 데이터 없으면 빈 리스트 반환

.fetchOne()

단 건 조회

- 결과가 없으면 : null

- 결과가 둘 이상이면 : com.querydsl.core.NonUniqueResultException

 

.fetchFirst()

limit(1).fetchOne()

.fetchResults()

페이징 정보 포함, total count 쿼리 추가 실행

.fetchCount()

count 쿼리로 변경해서 count 수 조회

 

 

3. 정렬

  • 데이터를 특정 컬럼 기준으로 정렬하고 싶을때 사용 한다.

 List<Member> result = queryFactory
 			.selectFrom(member)
 			.orderBy(member.age.desc(), member.username.asc().nullsLast()) .fetch();

 

정렬 문법

문법 기능

.orderBy()

리스트 정렬

  • .desc() → 내림차순

  • .asc() → 오름차순

 

 

4. 페이징

  • 다수의 row를 가진 결과를 나눠서 가져올 수 있다.

@Test
void paging() {
  //given & when
  QueryResults<Member> results = queryFactory.selectFrom(member)
      .orderBy(member.username.desc())
      .offset(1)
      .limit(2)
      .fetchResults();

  //then
  assertEquals(results.getTotal(), 4);
  assertEquals(results.getLimit(), 2);
  assertEquals(results.getOffset(), 1);
  assertEquals(results.getResults().size(), 2);
}

 

실제 쿼리문

select
    member0_.member_id as member_i1_1_,
    member0_.age as age2_1_,
    member0_.team_id as team_id4_1_,
    member0_.username as username3_1_ 
from
    member member0_ 
order by
    member0_.username desc limit ? offset ?

 

페이징 문법

문법 기능

.offset(1)

시작 인덱스 지정

.limit(2)

조희할 개수를 지정

 

참고: http://ojc.asia/bbs/board.php?bo_table=LecJpa&wr_id=315

http://www.querydsl.com/static/querydsl/4.0.1/reference/ko-KR/html_single/

반응형

'개발 > DBMS' 카테고리의 다른 글

[Querydsl] querydsl 학습_4  (0) 2020.11.23
[Querydsl] querydsl 학습_3  (0) 2020.09.04
[Querydsl] querydsl 학습_1  (0) 2020.08.19
[Querydsl] querydsl 적용시 주의점  (1) 2019.11.08