JPA의 다양한 쿼리 방법

D A S H B O A R D
D E V E L O P
S E C U R I T Y
 JPQL
 Criteria
 QueryDSL
 네이티브SQL
중요!!
Reference
전부 간단하게만 설명하고 JQPL과 QueryDSL을 사용하는 이유에 대해 설명한다. (자세한 내용은 다음 글에!!)

 JPQL

JPA를 사용하면 엔티티 객체를 중심으로 개발
JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어 제공
SQL과 문법 유사, SELECT, FROM, WHERE, GROUP BY,
HAVING, JOIN 지원JPQL은 엔티티 객체를 대상으로 쿼리
SQL은 데이터베이스 테이블을 대상으로 쿼리
사용 이유
문제는 검색 쿼리
검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색
모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능
애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요

예시

JPQL code

String jpql = "select m From Member m where m.username like ‘%kim%'"; List<Member> result = em.createQuery(jpql, Member.class) .getResultList();
Java
복사
JPQL과 SQL은 거의 흡사한 문법을 가지고 있다.
JPQL vs SQL
JPQL은 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
JPQL은 SQL을 추상화해서 특정 데이터베이스 SQL에 의존X → 다른 DB를 사용하면 다른 DB 쿼리로 잘 바뀌어져서 나간다.
JPQL을 한마디로 정의하면 객체 지향 SQL
약간의 단점!
JPQL의 Querry문은 String 으로 되어 있다. 그렇기 때문에 동적쿼리를 만드는 것이 굉장히 어려워지는데, 이는 후에 QueryDSL로 단점을 보완할 수 있다.
물론 MyBartis 같은 JQL도 역시 동적 쿼리를 편하게 짤 수 있다.

JPQL Query

Hibernate: /* select m From Member m where m.username like '%kim%' */ select m1_0.MEMBER_ID, m1_0.TEAM_ID, m1_0.USERNAME from Member m1_0 where m1_0.USERNAME like '%kim%' escape ''
SQL
복사

 Criteria

문자가 아닌 자바코드로 JPQL을 작성할 수 있음
JPQL 빌더 역할
JPA 공식 기능
단점: 너무 복잡하고 실용성이 없다.
Criteria 대신에 QueryDSL 사용 권장

예시

Criteria code

//Criteria 사용 준비 CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Member> query = cb.createQuery(Member.class); //루트 클래스 (조회를 시작할 클래스) Root<Member> m = query.from(Member.class); //쿼리 생성 CriteriaQuery<Member> cq = query.select(m).where(cb.equal(m.get("username"), “kim”)); List<Member> resultList = em.createQuery(cq).getResultList();
Java
복사
CriteriaBuilder : JAVA에서 지원하는 공식 문법
이렇게 JAVA 코드로 Query를 짜면 오타와 같은 humen error를 줄일 수 있다.
쉬워 보이지만, 복잡한 쿼리를 작성하게 되면 정말 엄청 복잡해진다. → 코드를 작성한 사람도 유지보수 하기 힘들다고 한다.

Criteria Query

Hibernate: /* select m From Member m where m.username like '%kim%' */ select m1_0.MEMBER_ID, m1_0.TEAM_ID, m1_0.USERNAME from Member m1_0 where m1_0.USERNAME like '%kim%' escape ''
SQL
복사

 QueryDSL

문자가 아닌 자바코드로 JPQL을 작성할 수 있음
JPQL 빌더 역할
컴파일 시점에 문법 오류를 찾을 수 있음
동적쿼리 작성 편리함
단순하고 쉬움
실무 사용 권장

예시

QueryDSL code

//JPQL //select m From Member m where m.username like ‘%kim%'" JPAFactoryQuery query = new JPAQueryFactory(em); QMember m = QMember.member; List<Member> list = query .select(m) .from(m) .where(m.name.like('kim')) .orderBy(m.id.desc()) // orderBy를 이용하고 싶다면 추가 .fetch();
Java
복사

참고

JPQL만 확실히 알아두면 QueryDSL은 당연하게 할 수 있게된다.
QueryDSL은 www.querydsl.com 공식문서에 정말 너무나도 잘 설명되어 있기 때문에, 참고하면서 하면 된다.

 네이티브 SQL

JPA가 제공하는 SQL을 직접 사용하는 기능
JPQL로 해결할 수 없는 특정 데이터베이스에 의존적인 기능
예) 오라클 CONNECT BY, 특정 DB만 사용하는 SQL 힌트

예시

네이티브 SQL code

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

참고

음.. 사용가능한 것은 맞지만 JPQL과 QueryDSL 그리고 MyBatis나 SpringJdbcTemplate와 같은 JDBC도 제공해주는데 굳이 사용할까 싶다!~!

 JDBC 직접 사용, SpringJdbcTemplate

JPA를 사용하면서 JDBC 커넥션을 직접 사용하거나, 스프링 JdbcTemplate, 마이바티스등을 함께 사용 가능
단 영속성 컨텍스트를 적절한 시점에 강제로 플러시 필요
예) JPA를 우회해서 SQL을 실행하기 직전에 영속성 컨텍스트 수동 플러시
궁금하면 Spring DB 접근기술 확인!!!