# 소개

* JPQL은 객체지향 쿼리 언어다.따라서 테이블을 대상으로 쿼리 하는 것이 아니라 엔티티 객체를 대상으로 쿼리한다.
* **JPQL은 SQL을 추상화해서 특정데이터베이스 SQL에 의존하지 않는다.**
* JPQL은 결국 SQL로 변환된다.

JPA는 다양한 쿼리 방법을 지원\
JPA Criteria, QueryDSL은 자바코드로 짜서 JPQL을 빌드하는 Generator 클래스의 모음.\
실무에서 거의 대부분 JPQL로 해결되지만 어쩌다 가끔은 네이티브 SQL/MyBatis, SpringJdbcTemplate 함께 사용할 수 있따.

1. **JPQL** : 표준 문법
2. JPA Criteria
3. **QueryDSL**
4. 네이티브 SQL : JPQL을 쓰더라도 가끔 DB에 종속적인 쿼리가 필요할 때.\
   특정 DB vendor에 종속적인 쿼리를 사용해야할 때.

   ex) Oracle - connectBy 같이 표준 SQL을 벗어나는 문법 써야할 때.
5. JDBC API 직접 사용, MyBatis, SpringJdbcTemeplate 함께 사용\
   MyBatis : 동적 쿼리 작성 용이.

JPQL : 엔티티를 대상으로 엔티티의 매핑 정보를 읽어서 적절한 쿼리문 작성한다.\
\=>동적 쿼리 작성 어려움

Criteria\
표준 스펙이지만 실무에서는 사용하지 않는다고 함!

* 문자가 아닌 자바코드로 JPQL을 작성할 수 있음
* JPQL 빌더 역할 : Typo 발생시 컴파일 오류로 발견 가능
* 동적 쿼리 작성 용이
* 단점: 너무 복잡하고 실용성이 없다.\
  \=>Criteria 대신에 **QueryDSL 사용 권장**

QueryDSL

* 문자가 아닌 자바코드로 JPQL을 작성할 수 있음
* JPQL 빌더 역할\
  컴파일 시점에 문법 오류를 찾을 수 있음
* 동적쿼리 작성 편리함
* 단순하고 쉬움
* **실무 사용 권장**\
  **=> 오픈소스이고 ,문서에 문법이나 사용 설명 자세하게 잘 나와있음.**\
  **JPQL을 알고 QueryDSL을 사용한다.**\
  **하지만 결론은 JPQL 문법을 알고 잘하면 QueryDSL은 그냥 얻어간다고 함.**

네이티브 SQL

* JPA가 제공하는 SQL을 직접 사용하는 기능
* JPQL로 해결할 수 없는 특정 DB 의존적인 기
* ex) 오라클 CONNECT BY, 특정 DB만 사용하는 SQL 힌트\
  \=>Hibernate가 모든 DB 지원함

```sql
String sql =
    “SELECT ID, AGE, TEAM_ID, NAME FROM MEMBER WHERE NAME = ‘kim’";
List<Member> resultList =
            em.createNativeQuery(sql, Member.class).getResultList();
```

JDBC 직접 사용, SpringJdbcTemplate 등\
(강사님은 네이티브 SQL보다 SpringJdbc Template이 더 편하다고 함.)

* JPA를 사용하면서 JDBC 커넥션을 직접 사용하거나, 스프링JdbcTemplate, 마이바티스등을 함께 사용 가능
* 단 **영속성 컨텍스트를 적절한 시점에 강제로 플러시 필요=>JPA와 관련없기 때문?**\
  flush는 commit 또는 query 가 있으면 DB에 데이터 넣는다!
* ex) JPA를 우회해서 **SQL을 실행하기 직전에 영속성 컨텍스트 수동 플러시⭐️⭐️⭐️⭐️⭐️**

**정리**

**JPQL** & QueryDSL을 정복하자!(95%)\
나머지 엄청나게 복잡한 통계성 쿼리는 SpringJdbcTemplate 사용\
(이마저도 J\&Q 조합이면 웬만하면 가능하다고 함.)

**JPQL을 철저하게 잘 해야한다. SQL과 문법이 거의 똑같기 때문에 SQL을 좀 했다면 어렵지 않을 것이다.**\
**+QueryDSL : JPQL을 문자로만 작성하면 버그가 많이 생기는데 QueryDSL을 함께 사용하면 버그나 오타가 발생하면 컴파일러가 잡아주기 때문에 동적 쿼리 작성도 쉽다!**
