스프링 공부/JPA

[JPA] 20. JPA에서 쿼리를 쓰는 방법

장아장 2023. 1. 17. 17:45

JPA에서 쿼리문을 만들어내는 방법은 엄청나게 다양하다. 

  • JPQL
  • JPA Criteria
  • QueryDSL
  • 네이티브 SQL
  • JDBC API 직접사용, MyBatis, SpringJdbcTemplcate 함꼐 사용

이렇게 다양한 방식이 있는데, 이에 대한 정리를 해보았다. 


JPQL

가장 단순한 조회

EntityManager.find()

a.get().get()

 

개발을 엔티티 객체 중심으로 개발할 수 있다. 

 

문제는, 데이터를 검색할 경우, 테이블을 기준으로 해야 한다. 

이 부분을 우리가 개발할 때 사용했던, 객체를 기준으로 할 수 없을까?

모든 db 데이터를 객체화 시키면 성능의 문제가 생긴다. 

 

이를 위해 객체 지향 JPQL이라는 객체 지향 쿼리문이 존재한다. 

JPQL =  엔티티를 대상으로 검색

SQL = 테이블을 대상으로 검색

이런 식으로 쿼리를 생성해 실행시켰을 경우, 

이렇게, 쿼리문을 만들어서 동작하는 JPQL을 볼 수 있다. 

원래 SQL문이었다면, select * from Member where username is like ‘%member%’;

이런식으로 되어야 하는데, 이를 JPQL이 h2에 맞게 수정해서 동작하게 한 것을 볼 수 있다. 

 

객체를 대상으로 검색을 진행하고, 특정 데이터베이스 SQL문에 의존하지 않는다. 

JPQL은 단순 문자열을 넣어 동작하게 된다. 

그렇기 때문에, 특정 상황에 맞는 동적 쿼리를 만들기 어렵다. 

왜냐하면, 특이한 경우에 따른 쿼리문 조작을 위해서는 java식으로는 문자열을 substring하고, 이를 다시 합치고를 반복해야한다. 

심지어 띄어쓰기, 콤마등을 관리해야 한다.

(진짜 내 상태가 콤마다 이건…)


Criteria

Criteria는 JPQL에서 해결하기 어려운 동적 쿼리문을 사용하기 조금 더 수월하게 해준다. 

이런 식으로 조회문을 만들 수 있다. 

자바 코드에서, 메서드를 불러와 사용하듯이 JPQL을 작성할 수 있다.

하지만 아주 쪼오오오오오오오옹오오오오오오오금 편해진다. 

코드를 보는 입장에서는 가시적으로 수월한 코드가 되기 힘들 수 있다. 

즉, 유지보수가 아주 힘들어진다. 

하지만, 자바의 코드 구성대로 이루어져있기 때문에, 동적으로 쓰기 편하고 문제가 있는 부분을 확인하기 수월하다. 

QueryDSL을 사용하는 것이 더 수월하다. 

(솔직히 이 정도면, 위에 JPQL 문자열 계산해서 조작하는게 나을 수 있다는 생각도 든다...)


QueryDSL

 

QueryDSL은 Cirteria처럼 자바 문법의 방식으로 쿼리문을 생성해준다. 

하지만, Criteria보다 직관적이고, 쓰기 쉽다는 장점이 있다. 

JPQL 빌더 역할을 한다. 

컴파일 시 오류로 문법상 문제를 찾을 수 있다. 

동적 쿼리 쓰기가 쉽다. 

단순하고 쉽기에 실무에서 권장된다. 


Native SQL

네이티브 SQL은

직접 사용하는 방식으로, JPQL로 사용할 수 없는 경우에 사용하게 된다. 

JDBC를 직접 사용한다. 

JPA를 사용하면서 동시에 JDBC 커넥션, 스프링 JDBC, 마이바티스등을 사용할 수 있다. 

영속성 컨텍스트를 적절한 상황에 강제적인 플러시가 필요하다.