# Hello JPQL

# 공부하기 전에

오랜만에 SQL강의를 듣는 기분이었다.
JPA에서 객체를 사용하기 위해 find()와 같은 것을 사용하여주었다. 이 방법으로는 객체를 하나밖에 꺼낼수 없다.

하지만 실무에서는 sql쿼리로 데이터를 일부 가져와야하는 sql을 날려야하는 경우도 있다. 이것을 날릴 수 있게 도움을 주는것이 바로 JPQL이다.

JPQL은 쿼리를 날리기 위해 EntityManager의 createQuary() 메소드를 사용한다. 파라미터로 String으로 쿼리를 만들어서 넣어주면된다. 이 때 특징으로 항상 별칭을 사용해야한다. "select m from Member m"와 같이 객체로 날리게 된다.

JPQL을 처음 만났을 때 굉장히 두려웠다. 과거 프로그래밍언어개론을 공부하며 인터프리터를 만들때 파싱을 위해 String을 열심히 파싱했던 경험이 생각났기 때문이다. 정적인 쿼리는 그냥 짜면 어려울게 없는데 실무에서는 동적인 쿼리를 훨씬 많이 쓸것 같음을 직감했다. 동적으로 쿼리를 짜려면.. if문으로 하드코딩해서 String을 넣어주어야하고 자칫 띄어쓰기도 잘못하면 에러가 나는 등의 험난한 앞길밖에 보이는게 없었다.

다행히도 동적쿼리를 구현하기 위해서 Querydsl이라는 것이 있다고 하였다. 그런데 Querydls도 결국은 JPQL로 구현되는 것이기 때문에 우선적으로 JPQL을 공부했다. 그 외 다른 방법으로 natural sql을 구사하는 방법과 Critria를 사용하는 방법이 있다.(Critria는 공부하면서 느낀건데 나도 내가 짠 쿼리지만 이해가 어려웠다.)

# JPQL에서의 프로젝션

SELECT를 할 때 어느 값을 가져올지에 대한 것이다. SELECT 숫자 혹은 문자 값타입 등등 여러개가 올 수 있다. 그런데 여기서 SELECT 후에 String과 Integer 이렇게 서로 다른 두개의 타입이 올 수 도 있다. 이 경우 Object로 받아서 넘겨사용해야한다.

# 페이징

페이징은 API를 굉장히 잘 제공해주기 때문에 편리하게 사용할 수 있었다.

# 조인

조인은.. 내 생각에 sql과 비슷한데 cross join하는 특별한 방법이 있었다.

# 서브쿼리

서브쿼리는 FROM절에서는 사용이 불가하다고 한다.. 굉장히 난해하다.

# 타입 표현

타입중에서 가장 특이한건 Enum 타입이다. 이 타입의 경우 패키지 명까지 모두 풀어써줘야한다. 하지만, :~로 값을 받아서 사용하면 그렇게 하지 안하도 된다.

# 조건문

Condition 문으로 case문 switch 문과 같은 것을 제공해준다. nullif와 같은 것도 제공해준다.

# 함수

SQL의 함수들을 대부분 지원해주는 것 같다. 특별하게 SIZE()라는 함수가 있는데 이 것은 OneToMany와 같은 객체에서 Many를 얼마나 갖고 있는지 size를 반환해준다. 그리고 사용자 지정 함수를 사용하기 위해서는 DB방언을 작성해 사용해야한다.(물론 세팅도 해줘야한다,)

배운게 너무 많은데.. 아직 머리속으로 대략 정리는 되는데 부족한거 같다.. 오늘 일단 자고 내일 일어나서 책으로 다시한번 복습해야겠다.