반응형

1. 개요

 - JPQL의 개념, 문법에 대해 알아보자.

 


2. 개념

 - JPQL은 Java Persistence Query Language의 약자로 자바에서 사용하는 객체 지향 쿼리 언어이다. 객체 지향이라는 말에 맞게 쿼리를 작성할 때 테이블을 대상으로 작성하는게 아닌 엔티티를 대상으로 작성한다.

 - JPQL은 결국에 SQL로 변환되며, 특정 데이터베이스에 의존하지 않는다.

 


3. JPQL 기본 문법

 - JPQL은 SQL 문법과 거의 동일하지만 다른 점이 몇가지 있다.

 1) 엔티티와 속성은 대소문자를 구분하므로 엔티티 클래스에 정의한 대로 사용해야 한다.

 2) SELECT, FROM, WHERE 과 같은 JPQL 키워드는 대소문자를 구분하지 않는다.

 3) SQL에서는 테이블 명을 입력했다면 JPQL에서는 테이블 명이 아닌 엔티티 명을 사용해야 한다.

 4) 별칭이 필수이다. (ex. select m from Member m)

 


4. TypeQuery와 Query

 - TypeQuery는 반환 값이 명확할 때, Query는 불명확할 때 사용한다.

	// 반환 타입이 Member 클래스로 명확
	TypedQuery<Member> typedQuery = 
		em.createQuery("select m from Member m", Member.class);
    
	// 반환 타입이 username, id로 불명확
	Query query = 
		em.createQuery("select m.username, m.id from Member m");

 


5. 결과 조회

 - 결과 조회 시 Query 및 TypeQuery의 메서드인 getResultList(), getSingleResult() 중 하나를 사용한다.

 

5.1. getResultList

 - 결과가 하나 이상일 때 리스트를 반환하고, 결과가 없을 때 빈 리스트를 반환한다.

 - null 체크 할 필요가 없다.

 

5.2. getSingleResult

 - 결과가 정확히 하나일 때 단일 객체를 반환하고, 없을 때 NoResultException, 둘 이상일 때 NonUniqueResultException 예외를 발생시킨다.

 - 이처럼 예외가 발생할 수 있기에 try, catch를 통한 핸들링이 필요하다. Spring Data JPA에서는 값이 없을 경우 예외를 발생시키는 부분을 개선하였으며 null 혹은 Optional 객체를 리턴하도록 구현되어 있다.

	TypedQuery<Member> list = 
		em.createQuery("select m from Member m", Member.class);

	// 결과가 하나 이상일 것을 예상하여 getResultList를 통해 반환받음
	List<Member> memberList = list.getResultList();
    

	TypedQuery<Member> single = 
		em.createQuery("select m from Member m where m.id = 1L", Member.class);

	// 결과가 하나일 것을 예상하여 getSingleResult를 통해 반환받음.
	// 만약 결과가 2개 이상이거나 없을 경우 예외가 발생함.
    Member singleMember = single.getSingleResult();

 


6. 파라미터 바인딩

 - 이름 기준과 위치 기준으로 바인딩 하는 방법이 있다.

 - 이름 기준으로 사용 시 쿼리에 ":" 구문을 사용하며, 위치 기준으로 사용 시 "?번호" 구문을 사용한다.

 - 위치 기반 바인딩은 쿼리 중간에 조건이 하나 더 추가될 경우 쿼리에 사용한 번호가 밀려 에러를 유발할 수 있다. 이에따라 위치 기반보다는 이름 기준 바인딩이 권장된다.

 

 * TypedQuery와 Query는 메서드 체이닝을 지원하기에 한번에 처리 가능하다.

	// 이름 기준 파라미터 바인딩
	TypedQuery<Member> query 
		= em.createQuery("select m from Member m where m.id = :id and m.username = :username", Member.class);
    query.setParameter("username", "심승경");
    query.setParameter("id", 1L);

    Member singleMember = query.getSingleResult();

	// 메서드 체이닝 방식
	Member singleResult 
		= em.createQuery("select m from Member m where m.id = :id and m.username = :username", Member.class)
            .setParameter("username", "심승경")
            .setParameter("id", 1L)
            .getSingleResult();
	
	// 위치 기준 파라미터 바인딩
	singleResult = 
		em.createQuery("select m from Member m where m.id = ?1 and m.username = ?2", Member.class)
            .setParameter(1, 1L)
            .setParameter(2, "심승경")
            .getSingleResult();

7. 참고

 - 자바 ORM 표준 JPA 프로그래밍 - 김영한

반응형

+ Recent posts