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");

검색하려는 속성에 대해서 파라미터를 바인딩 해줄 수 있다.

 

파라미터의 위치를 사용한 바인딩도 가능하지만 이는 사용하지 않는 것이 좋다. 중간에 다른 검색 조건이 들어올 경우 순서가 망가져버리기 때문.

 

 

 

 

+ Recent posts