본문 바로가기

JPA/JPQL

JPQL 함수

github 전체코드 주소(branch: function)

JPA 표준함수

JPA 표준함수(DB에 관계없이 사용가능): CONCAT, SUBSTRING, TRIM , LOWER, UPPER 등

// JPQL 표준함수
String query = "select concat('이름: ', s.name) from Student s";
List<String> school = em.createQuery(query, String.class).getResultList();
System.out.println("student name = " + school.get(0));
JPQL 표준함수는 DB(방언)에 상관없이 사용가능하다.
실행 후 로그는 다음과 같다.(H2 DB 기준)
Hibernate:select ('이름: '||student.name) from Student student
students name = 이름: code-mania

참고로 하이버네이트에서는 문자열결합을 CONCAT 함수 외에 || 연산자를 통해서도 가능하다.

 

DB종속함수

H2Dialect.java

해당 코드는 H2Dialect.java의 코드 중 일부이다.

registerFunction은 JPQL 함수를 등록하는 메서드이다.

registerFunction을 통해 등록된 함수들은 JPQL에서 사용가능하다.
따라서 H2Dialect를 방언으로 사용하는 경우 위와 같은 함수들을 사용가능한 것이다.

//DB 종속함수
String query = "select avg(s.age) from Student s";
List<Double> students = em.createQuery(query, Double.class).getResultList();
System.out.println("avg of ages = " + students.get(0));
H2Dialect에서 추가해준 avg 함수를 JPQL로 사용해보면 잘 실행되는 것을 확인할 수 있다.
실행 후 로그
Hibernate: select avg(cast(student.age as double)) from Student student
avg of ages = 21.0

사용자정의함수

JPA표준함수와 DB종속함수 외의 타입을 사용하고싶을 때에는 함수를 직접 등록해야 한다.
avg 함수를 average로 이름만 바꿔서 등록해보겠다.

 

MyH2Dialect.java

package hellojpa;

import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.function.AvgWithArgumentCastFunction;

public class MyH2Dialect extends H2Dialect {

    public MyH2Dialect() {
        this.registerFunction("average", new AvgWithArgumentCastFunction("double"));
    }
}

H2 DB를 사용하기 위해 H2Dialect는 상속받았고,

registerFunction 메서드를 통해서 average 함수를 등록했다.

 

persistence.xml

<property name="hibernate.dialect" value="hellojpa.MyH2Dialect"/>

그 후 persistence.xml에서 hibernate.dialect 속성에 내가 만든 MyH2Dialect를 넣어준다.

 

JpaMain.java

// 사용자정의함수
String query = "select average(s.age) from Student s";
List<Double> students = em.createQuery(query, Double.class).getResultList();
System.out.println("avg of ages = " + students.get(0));
average 함수가 잘 동작하는 것을 확인할 수 있다.
실행 후 로그
Hibernate: select avg(student0_.age) from Student student
avg of ages = 21.0

 

 

참고강의: 배달의 민족 개발팀장 김영한 강사님의 JPA 강의

'JPA > JPQL' 카테고리의 다른 글

N+1과 fetch join  (0) 2021.10.02
경로표현식  (0) 2021.10.02
JPQL에서의 Enum과 조건식  (0) 2021.09.17
서브쿼리  (0) 2021.09.16
조인  (0) 2021.09.15