원래의 조회방법
EntityManager.find()
a.getB().getC()
그런데 나이가 18살 이상인 회원을 모두 검색하고 싶을 때 어떻게 조회할까?
-> SQL을 날려야 한다.
엔티티 중심으로 개발하기 위해 JPQL이 등장한다.
- JPQL : 엔티티 객체를 대상으로 쿼리
- SQL : DB테이블 대상으로 쿼리
JPQL 예시코드
List<Member> result = em.createQuery(
"select m From Member m where m.username like '%kim%'",
Member.class
).getResultList();
변환된 SQL
Criteria
java 코드로 jpql을 짤 수 있게 해준다. (jpa 표준스펙)
유지보수가 어려워서 실무에서는 사용하지 않는다.
QueryDSL
java 코드로 jpql을 짤 수 있게 해준다. (오픈소스 라이브러리)
그래서 동적쿼리 작성이 편리하다.
SQL과 비슷하게 생겨서 유지보수도 편리하다.
Native Query
실제 해당 데이터베이스 종속적인 쿼리를 짜야할 때
생쿼리 짜야할때 사용한다.
em.createNativeQuery("SELECT MEMBER_ID, city, street, zipcode, USERNAME from MEMBER ")
.getResultList();
JDBC, SpringjdbcTemplate, mybatis
생 SQL 짜야할때 사용하는데, JPA와 관련없는 기술들이기 때문에 적절한 구간에서 영속성 컨텍스트를 flush 해주는 것이 필요하다.
JPQL (Java Persistence Query Language)
- 엔티티 객체를 대상으로 쿼리한다. (테이블 대상이 아니다)
- SQL을 추상화 했기 때문에 특정 DB에 의존하지 않는다.
- 결국 SQL로 변환된다.
문법
- select m from Member as m where m.age > 18
- 테이블 이름이 아니라 엔티티로 씀 (Member)
- 엔티티(Member), 속성(age) 은 대소문자 구분 O
- JPQL키워드(select, FROM, Where) 은 대소문자 구분 X
- 별칭 지정은 필수로 해야한다. (m) (as는 안써도됨)
집합과 정렬
select
COUNT(m), //회원수
SUM(m.age), //나이 합
AVG(m.age), //평균 나이
MAX(m.age), //최대 나이
MIN(m.age) //최소 나이
from Member m
GROUB BY, HAVING, ORDER BY 사용가능
TypedQuery, Query
TypedQuery : 반환 타입이 명확할 때 사용
Query : 반환 타입이 명확하지 않을 때 사용
TypedQuery<Member> query1 = em.createQuery("select m from Member m", Member.class);
Query query2 = em.createQuery("select m.username, m.age from Member m");
query1 은 타입이 명확하므로 (Member) TypedQuery 사용
query2 는 m.username, m.age 가 타입이 달라서 명확하지 않으므로 Query 사용
결과 조회 API
query.getResultList()
결과가 하나 이상일 때 사용
결과가 없으면 빈 리스트 반환
query.getSingleResult()
결과가 단 한개일때만 사용
결과가 없으면 : NoResultException 오류
결과가 2개이상 : NonUniqueResultException 오류
파라미터 바인딩
코드
Member result = em.createQuery("select m from Member m where m.username = :username", Member.class)
.setParameter("username", "member1")
.getSingleResult();
System.out.println("result.getUsername() = " + result.getUsername());
쿼리
'Web > JPA' 카테고리의 다른 글
EP13. JPQL 경로표현식, 페치조인, 다형성, named, 벌크연산 (0) | 2021.02.24 |
---|---|
EP12. JPQL (SQL식 JPQL변환) (0) | 2021.02.21 |
CascadeType.REMOVE vs orphanRemoval = true (0) | 2021.02.13 |
EP10. 값 타입 (0) | 2021.02.12 |
EP9. 프록시와 연관관계 관리 (0) | 2021.02.10 |