PHM 2023. 3. 13. 17:53

1. 시작 - JPQL vs Querydsl

 

2. 기본 Q-Type 활용

* Q 클래스 인스턴스를 사용하는 2가지 방법 *

// java
QMember qMember = new QMember("m");	// 별칭 직접 지정
QMember qMember = QMember.member;	// 기본 인스턴스 사용

 

 

3. 검색 조건 쿼리

- 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%’ 검색

 

4. 결과 조회

fetch() 리스트 조회, 데이터 없으면 빈 리스트 반환
fetchOne() - 단건 조회
    ㆍ결과가 없으면 : null
    ㆍ결과가 둘 이상이면 : com.querydsl.core.NonUniqueResultException
fetchFirst() limit(1).fetchOne()
fetchResults 페이징 정보 포함, total count 쿼리 추가 실행
fetchCount() count 쿼리로 변경해서 count 수 조회

 

5. 정렬

 

6. 페이징

* 카운트 쿼리가 조인 등등으로 이유로 복잡해지면 따로 sql을 짜준다.

 

7. 집합

 

8. 조인 - 기본 조인

기본 조인

- 조인의 기본 문법은 첫 번째 파라미터에 조인 대상을 지정하고, 두 번쨰 파라미터에 별칭(alias)으로 사용할 Q 타입을 지정하면 된다.

```java
join(조인 대상, 별칭으로 사용할 Q타입)
```

 

세타 조인

- 연관관계가 없는 필드로 조인

@Test
public void theta_join() {
    em.persist(new Member("teamA"));
    em.persist(new Member("teamB"));
    em.persist(new Member("teamC"));

    List<Member> result = queryFactory
            .select(member)
            .from(member, team)
            .where(member.username.eq(team.name))
            .fetch();

    assertThat(result)
            .extracting("username")
            .containsExactly("teamA","teamB");
}

- from 절에 여러 엔티티를 선택해서 세타 조인

- 외부 조인 불가능 → 다음에 설명할 조인 on을 사용하면 외부 조인 가능

 

9. 조인 - on절

- ON 절을 활용한 조인(JPA 2.1 부터 지원)

    ㆍ1. 조인 대상 필터링

    ㆍ2. 연관관계 없는 엔티티 외부 조인

 

1. 조인 대상 필터링

* 참고 : on절을 활용해 조인 대상을 필터링 할 때, 외부조인이 아니라 내부조인(inner join)을 사용하면, where 절에서 필터링 하는 것과 기능이 동일하다.

- 따라서 on 절을 활용한 조인 대상 필터링을 사용할 때, 내부 조인이면 익숙한 where 절로 해결하고, 정말 외부 조인이 필요한 경우에만 이 기능을 사용하자.

 

2. 연관관계 없는 엔티티 외부 조인

- 하이버네이트 5.1부터 `on`을 사용해서 서로 관계가 없는 필드로 외부 조인하는 기능이 추가되었다. 물론 내부 조인도 가능하다.

- 주의! 문법을 잘 봐야 한다. *leftJoin()* 부분에 일반 조인과 다르게 엔티티 하나만 들어간다.

    ㆍ일반조인 : `leftJoin(member.team, team)`

    ㆍon조인 : `from(member).leftJoin(team).on(xxx)`

 

10. 조인 - 페치 조인

- 페치 조인은 SQL에서 제공하는 기능이 아니다.

- SQL 조인을 활용해서 연관된 엔티티를 SQL 한번에 조회하는 기능이다. 주로 성능 최적화에 사용하는 방법이다.

 

11. 서브 쿼리

- `com.querydsl.jpa.JPAExpressions` 사용

 

* from 절의 서브쿼리 한계 *

- JPA JPQL 서브쿼리의 한계점으로 from 절의 서브쿼리(인라인 뷰)는 지원하지 않는다.

- 당연히 Querydsl도 지원하지 않는다.

- 하이버네이트 구현체를 사용하면 select 절의 서브쿼리는 지원한다.

- Querydsl도 하이버네이트 구현체를 사용하면 select 절의 서브쿼리를 지원한다.

 

* from 절의 서브쿼리 해결방안 *

1. 서브쿼리를 join으로 변경한다. ( 가능한 상황도 있고, 불가능한 상황도 있다. )

2. 애플리케이션에서 쿼리를 2번 분리해서 실행한다.

3. nativeSQL을 사용한다.

 

12. Case 문

* select, 조건절(where)에서 사용 가능 *

 

13. 상수, 문자 더하기

* 참고 : `member.age.stringValue()` 부분이 중요한데, 문자가 아닌 다른 타입들은 `stringValue()`로 문자로 변환할 수 있다.

- 이 방법은 ENUM을 처리할 때도 자주 사용한다.