[Querydsl] 기본 문법1
예제 도메인 모델
(코드는 생략..)
기본 문법
시작 - JPQL vs Querydsl
테스트 기본 코드
@SpringBootTest
@Transactional
public class QuerydslBasicTest {
@PersistenceContext EntityManager em;
@BeforeEach
public void before() {
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);
}
}
Querydsl vs JPQL
@Test
void startJPQL() {
// member1 찾기
Member findMember = em.createQuery(
"select m from Member m" +
" where m.username = :username")
.setParameter("username", "member1")
.getSingleResult();
}
@Test
void startQuerydsl() {
// member1 찾기
JPAQueryFactory queryFactory = new JpaQueryFactory(em);
QMember m = new QMember("m");
Member findMember = queryFactory
.select(m)
.from(m)
.where(m.username.eq("member1")) // 파라미터 바인딩 처리
.fetchOne();
}
EntityManager
로JPAQueryFactory
생성- Querydsl은 JPQL 빌더
- JPQL : 문자(실행 시점 오류), Querydsl : 코드(컴파일 시점 오류)
- JPQL : 파라미터 바인딩 직접, Querydsl : 파라미터 바인딩 자동 처리
JPAQueryFactory를 필드로
@SpringBootTest
@Transactional
public class QuerydslBasicTest {
@PersistenceContext EntityManager em;
JPAQueryFactory queryFactory;
@BeforeEach
public void before() {
queryFactory = new JPAQueryFactory(em);
// ...
}
}
JPAQueryFactory를 필드로 제공하면 동시성 문제는..?
동시성 문제는 JPAQueryFactory를 생성할 때 제공하는 EntityManager(em)에 달려있다. 스프링 프레임워크는 여러 쓰레드에서 동시에 같은 EntityManager에 접근해도, 트랜잭션 마다 별도의 영속성 컨텍스트를 제공하기 때문에, 동시성 문제는 걱정하지 않아도 된다.
기본 Q-Type 활용
Q클래스 인스턴스를 사용하는 2가지 방법
QMember qMember = new QMember("m"); // 별칭 직접 지정
QMember qMember = Qmember.member; // 기본 인스턴스 사용
기본 인스턴스를 static import와 함께 사용
import static study.querydsl.entity.QMember.*;
@Test
void startQuerydsl() {
// member1 찾기
Member findMember = queryFactory
.select(member)
.from(member)
.where(member.username.eq("member1"))
.fetchOne();
}
[참고] : 같은 테이블을 조인해야 하는 경우가 아니면 기본 인스턴스를 사용.
검색 조건 쿼리
기본 검색 쿼리
@Test
void search() {
Member findMember = queryFactory
.selectFrom(member)
.where(member.username.eq("member1")
.and(member.age.eq(10)))
.fetchOne();
}
- 검색 조건은
.and()
,.or()
를 메서드 체인으로 연결할 수 있다.
[참고] :
select
,from
을selectFrom
으로 합칠 수 있다.
JPQL이 제공하는 모든 검색 조건 제공
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%’ 검색
...
AND 조건을 파라미터로 처리
@Test
void searchAndParam() {
List<Member> result = queryFactory
.selectFrom(member)
.where(member.username.eq("member1"), member.age.eq(10))
.fetch();
}
where()
에 파라미터로 검색조건을 추가하면AND
조건이 추가됨- 이 경우
null
값은 무시 -> 메서드 추출을 활용해서 동적 쿼리를 깔끔하게 만들 수 있다.
<출처 : 인프런 - 실전! Querydsl(김영한)>
댓글남기기