출처
https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
목차
서론
가장 단순하게 데이터를 조회하는 방법은 EntityManager.find(), 객체 그래프 탐색(a.getB())을 이용한 방법입니다.
하지만, 나이가 18살 이상인 모든 회원을 조회하는 것 같이 조건이 걸린 데이터 조회는 어떻게 해야 할까요?
이에 JPA는 다양한 쿼리 방법을 지원합니다. 종류와 특징에 대해 알아보겠습니다.
JPQL
- JPA는 테이블이 아닌 엔티티 객체를 중심으로 개발됩니다.
- 문제는 검색을 할 때 테이블이 아닌 엔티티 객체를 대상으로 검색해야 합니다.
- 모든 데이터베이스 데이터를 객체로 변환하여 검색하는 것은 불가능합니다.
- 조건을 통해 애플리케이션에서 필요한 데이터만 데이터베이스에서 불러오려면, 결국 검색 조건이 포함된 SQL이 필요합니다.
- 따라서 JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공합니다.
특징
String jpql = "select m From Member m where m.name like ‘%hello%'";
List<Member> result = em.createQuery(jpql, Member.class)
.getResultList();
- SQL과 문법이 유사합니다. (ANSI 표준 SQL - SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원)
- JPQL은 엔티티 객체를 대상으로 쿼리를 날립니다.
- SQL은 데이터베이스 테이블을 대상으로 쿼리를 날립니다.
- JPQL로 작성한 쿼리는 SQL로 변환되어 실행됩니다.
- JPQL은 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 SQL 입니다.
- SQL을 추상화했기 때문에 특정 데이터베이스 SQL에 의존하지 않습니다.
[변환되어 실행된 SQL]
select
m.id as id,
m.age as age,
m.USERNAME as USERNAME,
m.TEAM_ID as TEAM_ID
from
Member m
where
m.age>18
✔️JPQL은 엔티티 대상, SQL은 테이블 대상
Criteria
- 문자가 아닌 자바 코드로 JPQL을 작성할 수 있습니다.
//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();
- 문자가 아닌 자바 코드로 작성함으로써, 오타 입력 시 컴파일 오류가 발생하고, 동적 쿼리 생성이 용이합니다.
- JPQL 빌더 역할을 합니다.
- JPA에서 제공하는 공식 기능입니다.
- 단점: 너무 복잡하고 실용성이 없습니다.
- Criteria 대신에 QueryDSL 사용을 권장합니다.
QueryDSL
- 문자가 아닌 자바 코드로 JPQL을 작성할 수 있습니다.
//JPQL: select m from Member m where m.age > 18
JPAQueryFactory query = new JPAQueryFactory(em);
QMember m = QMember.member; //Member에 관한 SQL
List<Member> list = query.selectFrom(m)
.where(m.age.gt(18))
.orderBy(m.name.desc())
.fetch();
- 문자가 아닌 자바 코드로 작성함으로써, 오타 입력 시 컴파일 오류가 발생하고, 동적 쿼리 생성이 용이합니다.
- JPQL 빌더 역할을 합니다.
- 단순하고 쉽습니다. (JPQL과 거의 비슷합니다. 따라서, JPQL만 잘 알아두면 간편하게 사용할 수 있습니다.)
- 실무 사용을 권장합니다.
네이티브 SQL
- JPQL로 해결할 수 없는 특정 데이터베이스에 의존적인 기능을 제공할 떄 사용합니다.
- 예) 오라클의 CONNECT BY 또는 특정 DB만 사용하는 SQL 힌트
- JPA가 제공하는 SQL을 직접 사용하는 기능입니다.
String sql = “SELECT ID, AGE, TEAM_ID, NAME FROM MEMBER WHERE NAME = ‘kim’";
List<Member> resultList = em.createNativeQuery(sql, Member.class).getResultList();
JDBC 직접 사용, SpringJdbcTemplate 등
- JPA를 사용하면서 JDBC 커넥션을 직접 사용하거나, 스프링 JdbcTemplate, 마이바티스 등도 함께 사용할 수 있습니다.
- 단, 필요한 시점에 영속성 컨텍스트 강제 플러시가 필요합니다.
Member member = new Member();
member.setUsername("member1");
em.persist(member);
//em.flush(); //강제 플러시
dbconn.executeQuery("select * from member"); //flush를 하지 않으면, db에 Member 객체가 없다.
'Backend > JPA' 카테고리의 다른 글
[JPQL] 프로젝션 (0) | 2023.12.24 |
---|---|
[JPQL] 객체 지향 쿼리 기본 문법과 기능 (0) | 2023.12.24 |
[JPA] 값 타입 (0) | 2023.12.20 |
[JPA] 프록시와 연관관계 관리 (0) | 2023.12.20 |
[JPA] 고급 매핑 (상속 관계 매핑, 공통 속성 매핑) (0) | 2023.12.20 |