전부 간단하게만 설명하고 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은 당연하게 할 수 있게된다.
•
네이티브 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을 실행하기 직전에 영속성 컨텍스트 수동 플러시