JPA를 사용해 엔티티 객체를 중심으로 개발을 진행하듯이 JPQL을 사용하여 엔티티 객체를 대상으로 쿼리를 작성할 수 있다.
JPQL로 작성한 쿼리는 SQL로 변환되어 디비에 적용된다.
JPQL은 테이블과 컬럼명을 대상으로 짜는 쿼리가 아니다. 엔티티 객체와 그 속성에 대해 작성하는 쿼리이다. 그렇기 때문에 엔티티 객체, 속성에 대해서는 반드시 대소문자를 구분해야 한다.
(쿼리 타입) - JPQL 쿼리는 두 가지 타입으로 받을 수 있다.
1. TypedQuery<T> - 조회하는 데이터의 타입이 명확할 때 사용
TypedQuery<Member> query = em.createQuery("select m from Member m", Member.class);
Member 객체를 통째로 조회한다. 조회되는 자료의 타입을 명시할 수 있다.
TypedQuery<String> query = em.createQuery("select m.username from Member m", String.class);
Member의 username 하나만 조회한다. String으로 타입이 명확하다.
2. Query - 조회하는 데이터의 타입이 명확하지 않을 때
Query query = em.createQuery("select m.username, m.age from Member m");
서로 타입이 다른(String, int) username, age를 조회한다. 결과 데이터에 대한 타입을 명확하게 나타낼 수 없으므로 TypedQuery<T>가 아닌 Query를 사용한다.
엔티티 객체의 여러 속성을 한 번에 조회하여 쿼리 타입을 특정할 수 없을 때는 아래와 같이 Object[]로 받아서 다루는 방법이 있다.
List<Object[]> resultList = em.createQuery("select m.username, m.age from Member m").getResultList();
Object[] result = resultList.get(0);
String name = result[0];
int age = result[1];
주의 - query.getResultList(), query.getSingleResult()
메서드 이름에서도 알 수 있듯이 getResultList()는 쿼리의 결과가 여러 개일 때 그것들을 List로 묶어서 반환하고, getSingleResult()는 쿼리 결과가 하나 뿐일 때 사용한다.
getResultSet()은 결과를 꺼냈을 때 조회된 행이 없다면 null을 반환하지만 getSingleResult()은 예외를 발생시킨다. 결과가 여럿이어도 예외를 발생시킨다.
즉, 결과가 단 하나만 나오는 것이 보장될 때만 사용해야 한다, (스프링 데이터 JPA에서는 예외 발생 시 null을 반환하도록 설정되어 있다고 한다)
(파라미터 바인딩) - JPQL에서 사용할 파라미터를 직접 입력하지 않고 따로 세팅해줄 수 있다.
TypedQuery<Member> query =
em.createQuery("select m from Member m where m.username = :username", Member.class);
query,setParameter("username", "member1");
검색하려는 속성에 대해서 파라미터를 바인딩 해줄 수 있다.
파라미터의 위치를 사용한 바인딩도 가능하지만 이는 사용하지 않는 것이 좋다. 중간에 다른 검색 조건이 들어올 경우 순서가 망가져버리기 때문.
'김영한님 스프링 강의 정리 > JPA' 카테고리의 다른 글
명시적 조인과 묵시적 조인 (0) | 2021.03.10 |
---|---|
JPQL - 프로젝션과 페이징 기능 (0) | 2021.03.09 |
값 타입과 immutable 객체 (0) | 2021.03.03 |
임베디드 타입 (복합 값 타입) (0) | 2021.03.02 |
JPA의 데이터 타입 (엔티티 타입, 값 타입) (0) | 2021.03.02 |