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를 구현하면 좋을 것 같다.
'IT > JPA' 카테고리의 다른 글
LocalDate, LocalTime JPA Timezone 문제 (0) | 2020.03.25 |
---|---|
[JPA] null value was assigned to a property of primitive type setter of (0) | 2019.11.14 |
Spring Data JPA + QueryDsl (2) | 2019.09.09 |
@OneToMany 단방향을 @ManyToOne 양방향으로 (2) | 2019.08.28 |
Spring Data JPA 기초 #1 (7) | 2019.01.07 |