지루하게 반복되는 CRUD 문제를 세련된 방법으로 해결
개발자는 인터페이스만 작성한다
스프링 데이터 JPA가 구현 객체를 동적으로 생성해서 주입
제네릭은 <엔티티, 식별자>로 설정한다.
JpaRepository를 인터페이스 상속 받아 사용하면 된다.
기본적인 CRUD는 구현할 필요가 없다.
메소드 이름으로 Query를 정의하며 @Query
어노테이션을 이용하여 직접 JPQL을 지정할 수 있다.
SQL, JPQL을 코드로 작성할 수 있도록 도와주는 빌더 API
JPA에서 복잡한 쿼리가 필요한 경우에, JPA 자체 제공 Method만으로 해결하기 어렵기 때문에, Native Query
를 고려하게 된다.
이 경우 String
값을 직접 이어 붙여가며 작성하기 때문에 복잡하며 오타가 발생할 확률이 높다.
이 쿼리를QueryDSL
을 통해 수행할 경우 Native Query
의 단점을 극복할 수 있다
먼저 쿼리를 Java
로 작성하고 가독성이 좋으며 메소드 타입에 맞지 않는 파라미터를 넘길 경우 컴파일 오류가 발생해 버그를 방지한다.
=> IDE의 도움을,,,, 받을 수 있으며 컴파일 타임에 오류를 잡아 코드 실수를 크게 줄인다. 그리고 제일 큰 이유는 동적 쿼리이다.
QueryDSL 설정을 마치면 빌드 시 @Entity가 붙은 클래스를 찾아 자동으로 생성된다. 이러한 Q class들을 QueryDSL을 사용하여 메소드 기반으로 쿼리 작성 시 Domain Class의 구조를 설명해주는 메타 데이터 역할을 하며 쿼리의 조건을 설정할 때 사용된다.
일반적으로 Q파일은 Git에 업로드하면 안 된다.
Entity Manager를 JPAQueryFactory에 넣고 Q클래스 객체를 가지고 쿼리를 Java코드로 짤 수 있다.
select()
from()
selcetFrom()
(select + from 한번에 처리)
where()
, and()
, or()
orderBy()
등..
Member findMember = jpaQueryFactory
.select(m)
.from(m) //selectFrom(m)으로 치환 가능
.where(m.id.eq(1L)).and(m.age.eq(20))
.fetchOne();
eq()
, ne()
, not()
== , != ,!= (not은 마지막에 붙여준다.)
isNotNull()
Null이 아니면 true
in(1,2,3,4)
, notIn(1,3,5)
, between(10,20)
원소에 있는경우, 원소에 없는경우, 10 ~ 20 사이
x.goe(y)
x >= y
x.gt(y)
x > y
x.loe(y)
x <= y
x.lt(y)
x < y
like()
contains()
startsWith()
fetch()
리스트 조회 없으면 빈 리스트 반환
fetchOne()
단일 객체 반환, 없으면 null, 둘 이상이면 NonUniqueResultException
fetchFirst()
가장 먼저 찾는걸 반환
fetchResults()
페이징 정보 포함, total 쿼리 추가 실행
페이징이 아니라면 지양
fetchCount()
count 쿼리로 갯수 조회 (long 타입)
desc()
, asc()
nullsLast()
, nullsFirst()
null 데이터 순서 부여
select m from Member m where m.age > 18
JPAFactoryQuery query = new JPAQueryFactory(em);
QMember m = QMember.member;
List<Member> memberList =
query.selectFrom(m)
.where(m.age.gt(18))
.orderBy(m.name.desc())
.fetch();
BooleanBuilder
에 조건을 넣고 쿼리를 실행시키면 된다. 또한 원하는 필드만 뽑아서 DTO로 export하는 기능도 QueryDSL을 통해 할 수 있다. String name = "member";
int age = 9;
QMember m = QMember.member;
BooleanBuilder builder = new BooleanBuilder();
if(name != null) {
builder.and(m.name.contains(name));
}
if(age != 0) {
builder.and(m.age.gt(age));
}
List<Member> memberList =
query.selectFrom(m)
.where(builder)
.fetch();
https://querydsl.com/static/querydsl/4.0.1/reference/ko-KR/html_single/