java/JPA

JPA- JPQL(Java Persistence Query Language)

#풀닢 2023. 4. 11. 13:51

JPQL(Java Persistence Query Language)

 

 

엔티티 객체를 중심으로 개발할 수 있는 객체 지향 쿼리
SQL보다 간결하며 DBMS에 상관 없이 개발이 가능하다.
(방언을 통해 해결되며 해당 DBMS에 맞는 SQL을 실행한다. 특정 DBMS에 의존하지 않는다.)
JPQL find() 메소드를 통한 조회와 다르게 항상 데이터베이스에 SQL을 실행해서 결과를 조회한다.
(영속성 컨텍스트에 이미 존재하면 기존 엔티티를 반환하고 조회한 것은 버린다.)
JPQL은 엔티티 객체를 대상으로 쿼리를 질의하고 SQL은 데이터베이스의 테이블을 대상으로 질의한다.
, JQPL은 결국 SQL로 변환 된다

 

JPQL 사용 방법
1. 작성한 JPQL(문자열)을 em.createQuery 메소드를 통해 쿼리 객체로 만든다. 쿼리 객체는 TypedQuery, Query 두 가지가 있다.
TypedQuery : 반환할 타입을 명확하게 지정하는 방식일 때 사용(쿼리 객체의 메소드 실행 결과로 지정한 타입이 반환 된다.)

Query : 반환할 타입을 명확하게 지정할 수 없을 때 사용(쿼리 객체 매소드의 실행 결과로 Object or Object[]이 반환 된다.)

2. 쿼리 객체에서 제공하는 메소드 getSingleResult() 또는 getResultList()를 호출해서 쿼리를 실행하고 데이터베이스를 조회한다.
 getSingleResult() : 결과가 정확히 한 행일경우 사용 (없거나 많으면 예외 발생) - 단일 행 조회
 getResultList() : 결과가 2행 이상일 경우 사용하며 컬렉션을 반환한다. (결과가 없으면 빈 컬렉션 반환) - 여러 행 조회


단일메뉴 조회 -> 반환 할 타입을 명확하게 지정하는 방식

그래서 TypedQuery를 써야 한다. 쿼리 객체는 query.~(); 이렇게 쓰기

 

//TypedQuery를_이용한_단일메뉴_조회_테스트
String jpql = "SELECT m.menuName FROM section01_menu as m WHERE m.menuCode = 7";
TypedQuery<String> query = entityManager.createQuery(jpql, String.class);
String resultMenuName = query.getSingleResult();

//Query를_이용한_단일메뉴_조회_테스트
String jpql = "SELECT m.menuName FROM section01_menu as m WHERE m.menuCode = 7";
Query query = entityManager.createQuery(jpql);		//결과 값의 타입을 명시하지 않음
Object resultMenuName = query.getSingleResult();	//결과 값은 Object로 반환 된다

 TypedQuery와 Query의 차이는 반환 타입에 있다.

TypedQuery는 반환 타입을 지정해주는 제네릭 타입을 사용하여 반환값의 타입을 명시할 수 있다.

즉, TypedQuery<String>을 사용하면 getSingleResult() 메소드의 반환 타입이 String으로 결정되고 이렇게 반환 타입을 명시해주면, 반환되는 결과값을 타입 캐스팅하지 않아도 된다.

반면에 Query는 제네릭 타입을 사용하지 않는다. getSingleResult() 메소드는 Object를 반환하므로, 반환되는 결과값을 타입 캐스팅하여 사용해야 합니다.
차이점은 TypedQuery를 사용하는 것이 타입 안정성(type safety)을 보장해주는 것이고, Query를 사용하는 것은 타입 캐스팅 등의 추가 작업이 필요하다는 점에서 차이가 있다.

 


//distinct를_활용한_중복제거_여러_행_조회_테스트
String jpql = "SELECT DISTINCT m.categoryCode FROM section01_menu m";
//in_연산자를_활용한_조회_테스트
String jpql = "SELECT m FROM section01_menu m WHERE m.categoryCode IN (6, 10)";
//like_연산자를_활용한_조회_테스트
String jpql = "SELECT m FROM section01_menu m WHERE m.menuName LIKE '%마늘%'";

 

 

파라미터 바인딩하는 방법 
 1. 이름 기준 파라미터(named parameters)
  ':' 다음에 이름 기준 파라미터를 지정한다.
 2. 위치 기준 파라미터(positional parameters)
  '?' 다음에 값을 주고 위치 값은 1부터 시작한다.

//이름 기준
String jpql = "SELECT m FROM section02_menu m WHERE m.menuName = :menuName";
		
List<Menu> menuList = entityManager.createQuery(jpql, Menu.class)
		.setParameter("menuName", menuNameParameter)
		.getResultList();
        
//위치 기준
String jpql = "SELECT m FROM section02_menu m WHERE m.menuName = ?1";
		
List<Menu> menuList = entityManager.createQuery(jpql, Menu.class)
		.setParameter(1, menuNameParameter)
		.getResultList();

 

위치기준
SMALL