반응형
JPA는 다양한 쿼리 방법을 지원한다.
- JPQL
- JPA Criteria
- QueryDSL
- 네이티브 SQL
- JDBC API 직접 사용, MyBatis, SpringJdbcTemplate 함께 사용
다양한 쿼리 방법 맛보기
우리가 배운 것 중에 가장 간단한 조회 방법은 EnfifyManager.find() 를 한 뒤, 객체 그래프를 탐색하는 방법이었다. (a.getB().getC())
이때, 만약 나이가 18살 이상인 회원을 모두 검색하고 싶다면? JPQL을 사용해보자.
JPA의 문제점
- JPA를 사용하면 엔티티 객체를 중심으로 개발
- 문제는 검색 쿼리
: 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색해야 한다.- 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능하다.
→ 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요하다!
- 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능하다.
JPQL 특징
- 객체 지향 쿼리 언어
- SQL과 문법이 유사하다. (SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원)
- JPQL : 엔티티 객체를 대상으로 쿼리 / SQL : 데이터베이스 테이블을 대상으로 쿼리
검색 예시
String jpql = "select m from Member m where m.id > 18";
List<Member> result = em.createQuery(jpql, Member.class).getResultList();
- 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
- 장점 : SQL을 추상화해서 특정 데이터베이스 SQL에 의존 X
Criteria 소개
JPQL : 결국은 단순한 String이다. -> 동적 쿼리를 만들기 어렵다.
대안 : Criteria
자바코드로 JPQL을 작성할 수 있도록 도와주는 방식이며 JPQL의 빌더 역할이라고 보면된다.
장점 : 자바 코드여서 오타가 나면 컴파일 오류가 난다. 동적 코드 가능
단점 : 유지보수가 너무 어렵다. (본인이 만들어도 나중에 다시 보면 이해하기 힘들다.)
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Member> query = cb.createQuery(Member.class);
Root<Member> m = query.from(Member.class);
CriteriaQuery<Member> cq = query.select(m);
String username = "da";
if (username != null) {
cq = cq.where(cb.equal(m.get("name"), "kim"));
}
List<Member> result = em.createQuery(cq).getResultList();
사용하기에 너무 복잡하고 실용성이 없어 실무에서 사용하지 않으니 참고만 해보자. Criteria 대신에 QueryDSL 사용을 권장한다.
QueryDSL 소개
- 문자가 아닌 자바 코드로 JPQL을 작성할 수 있다.
- JPQL 빌더 역할을 하고, 컴파일 시점에 문법 오류를 찾을 수 있다.
- 동적 쿼리를 작성하기 편리하다.
- 단순하고 쉽기 때문에 실무 사용 적극 권장한다.
//JPQL
JPAFactoryQuery query = new JPAQueryFactory(em);
QMember m = QMember.member;
List<Member> list = query
.selectFrom(m)
.where(m.age.gt(18))
.orderBy(m.name.desc())
.fetch();
네이티브 SQL 소개
- JPA가 제공하는 SQL을 직접 사용
- JPQL로 해결할 수 없는 특정 데이터베이스에 의존적인 기능들
List<Member> resultList = em.createNativeQuery("select MEMBER_ID, city, street, zipcode, USERNAME, from MEMBER", Member.class).getResultList();
JDBC 직접 사용
JPA를 사용하면서 JDBC 커넥션을 직접 사용하거나, 스프링 JdbcTemplate, Mybatis 등 함께 사용 가능하다.
단, 영속성 컨텍스트를 적절한 시점에 강제로 플러시 필요하다. 즉, JPA에서 지원하는 기본 쿼리 문들은 모두 flush()처리를 해주지만, JDBC를 직접사용하는 경우 직접 flush()가 필요하다.
이 글은 김영한 님의 "자바 ORM 표준 JPA 프로그래밍 - 기본 편" 강의를 듣고 정리한 내용입니다.
반응형