본문 바로가기
IT/JPA

JPQL, NativeSQL, Criteria, QueryDSL, JOOQ...

by 최고영회 2019. 9. 6.
728x90
반응형
SMALL

JPA를 이용해서 Application 의 모든 로직을 처리하는 것은 사실상 어렵다고 본다. 

단순한 CRUD와 일반적인 CUD에 대해서는 JPA로 아주 큰 효과를 볼 수 있을 것으로 보이나 

실제 우리가 만드는 Application 들은 복잡한 구조로 데이터를 읽을 필요가 있다. 

JPA가 기본적으로 제공하는 기능들로 복잡한 구조로 데이터를 읽는 것은 어려우며

보다 쉬운 방법들이 필요하다.

 


 

JPQL

 - 이름만으로 어떤 녀석인지 느낌이 온다.

 - 테이블이 아닌 Entity 객체를 대상으로 검색하는 객체지향 쿼리이며 

 - SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다. 

 - 영속성 컨텍스트에서 찾지 않고 항상 데이터베이스를 조회 한다. 

 - JPQL로 조회한 엔티티는 영속 상태가 된다. 

 - JPQL은 정말 많은 장점들을 가지고 있으나 너무x2 복잡하기 때문에 사용에는 쉽지 않는 큰 단점이 있다. 

 

Native SQL

 - JPA에서 JPQL 대신 직접 SQL 을 사용하는 방법이다. 

 - JPQL에서 지원하지 않는 여러 비표준 기능(ex. 특정 데이터베이스에서만 지원하는 함수, 문법, SQL 힌트.. 등) 들을
   사용하고 싶을 때 Native SQL을 사용할 수 있다. 

 - 다만, Native SQL을 사용할 경우 데이터베이스에 의존하는 SQL을 작성하게 되기 때문에
   JPA가 갖는 큰 장점 (데이터베이스에 대한 비의존성)을 잃게 된다. 

 

Criteria, QueryDSL, JOOQ

 - JPQL을 편하게 작성하도록 도와주는 빌더 클래스 모음이며 비표준 오픈소스 프레임워크

 - Criteia는 장점이 나주 많지만 이 모든 장점을 상쇄할 정도로 복잡하고 장황하다. 
   사용하기에도 불편하고 가독성도 매우 떨어진다. 

 - QueryDSL은 Entity 클래스를 기반으로 QueryDSL 쿼리 전용 클래스를 만들어야 하는 단점이 있으나 
   자동으로 생성가능하며 사용이 매우 쉽고 직관적이다. 

 - JOOQ은 QueryDSL 과 비교대상이 되는 프레임워크로 QueryDSL과 유사하며 Return 해주는 Class가
   Entity가 아닌 별도의 Class 인 것이 단점으로 꼽힌다. 
   그리고 JOOQ은 유료데이터베이스에 대해서는 역시 유료다. (ex. Oracle을 사용하게 되면 JOOQ도 구매해야 함)

 

JDBC 직접 이용, MyBatis

 - JDBC를 직접 이용하거나 MyBatis 와 같은 SQL Mapper를 이용할 수도 있다. 

 - JDBC나 MyBatis를 JPA와 함께 사용하려면 영속성 컨텍스트를 적절한 시점에 강제로 플러시 해야 한다.

 - 최악의 시나리오는 영속성 컨텍스트와 데이터베이스를 불일치 상태로 만들어 데이터의 무결성을 훼손할 수 있다.
   Spring AOP를 이용하여 JPA를 우회해서 데이터베이스에 직접 접근하는 메서드를 호출할 때마다 영속성 컨텍스트를 
   플러시하면 이 문제는 해결된다. 

 

Native SQL, JDBC 직접이용, MyBatis와 같은 문자기반 쿼리의 단점은 SQL에 오타가 있어도 컴파일 시점에는

오류를 찾을 수 없기 때문에 테스트가 부족하면 실제 운영 환경에서 오류가 발생하는 큰 문제가 있다는 것이다. 

 


 

개인적으로 JPQL을 제대로 이해하고 JPQL을 편하게 작성하도록 도와주는

빌더 클래스모음의 프레임워크인 QueryDSL 이나 JOOQ을 추천한다. 

그리고 CUD는 Spring DATA JPA를,

복잡한 R은 QueryDSL과 같은 프레임워크를 이용하여 CQS 로 API를 구현하면 좋을 것 같다. 

 

728x90
반응형
LIST