본문 바로가기
  • 개발공부 및 일상적인 내용을 작성하는 블로그 입니다.
JPA

JPQL - JPQL 기본(10)

by 방구석 대학생 2020. 11. 24.

"인프런 - 자바 ORM 표준 JPA 프로그래밍 강의를 듣고 작성한 글 입니다."

www.inflearn.com/course/ORM-JPA-Basic#

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 프로그

www.inflearn.com

 

JPQL 사용자 정의 함수

만약 지금까지 설명해온 JPQL 에서 제공하는 표준 함수로 해결이 불가능한 문제가 발생한다면 사용자 정의 함수를 활용할 수 있다.

- 개발을 하다보면 데이터베이스에 함수가 있을 수 있다, 그 함수들을 불러다 써야 하는데 DB 쿼리를 하는 경우 쿼리 내부에서 함수가 적용되겠지만 JPQL 은 그 함수를 알 수 있는 방법이 없다.

- 그렇기 때문에 표준 문법을 제공하며, 그것을 Hibernate 를 사용하기 전에 데이터베이스 방언에 추가해 놓아야 한다.

(물론 그 이전에 JPQL 에서 제공하는 표준 함수가 아닌 데이터베이스 방언별로 가지고 있는 함수들 또한 존재한다.)

- 사용자 정의 함수의 표준 문법은 아래와 같다.

-> select function('group_concat', i.name) from Item i // 사용하는 DB 방언을 상속받고 사용자 정의 함수를 등록한다.

 

여기서 예제에 들어가기에 앞서 이미 우리가 만들어놓은 사용자 정의 함수가 있다고 가정한다.

이번 예제에서는 이미 만들어놓은 함수를 'group_concat' 함수 (이미 데이터베이스 방언에 존재하는 함수)라고 가정하고 수행해보자.

 

우선 프로젝트에서 dialect 클래스를 만들어야 한다. 이후 만들어놓은 사용자 정의 함수를 각 데이터베이스 방언에 맞는 형태로 코드를 작성하여 데이터베이스 방언에 추가해준다.

1. dialect 패키지 생성 -> 2. MyH2Dialect 와 같은 클래스 생성 (생성한 클래스는 사용하는 데이터베이스 방언을 상속 받아야 한다.)

- MyH2Dialect.java

public class MyH2Dialect extends H2Dialect {
	public MyH2Dialect() {
		registerFunction("group_concat", new StandardSQLFunction("group_concat", StandardBasicTypes.STRING));
		// group_concat 이라는 함수를 이미 만들어 두었다고 가정한다.
		/* 생성자 내부에서 작성한 코드에 대한 부분은 상속받은 H2Dialect 클래스의 내용에서
		함수의 형태를 확인하여 작성해줄 수 있다. */
	}
}

 

위와 같이 데이터베이스 방언에 만들어놓은 함수를 등록하고 나서 함수를 사용하려면 persistence.xml 파일의 dialect 옵션을 변경해주어야 한다.

<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
-> <property name="hibernate.dialect" value="dialect.MyH2Dialect"/>

* 직접 만든 사용자 함수를 등록해놓은 클래스의 경로, 기존의 데이터베이스 방언을 상속받기에 원래 등록되어 있는 데이터베이스 방언의 함수 또한 사용할 수 있다.

 

이후 함수를 실제로 사용하려면 다음과 같이 코드를 작성해서 사용해주자.

-> String query = "select function('group_concat', m.username) From Member m";

// 여기서 사용한 group_concat 이라는 함수는 이미 데이터베이스 방언에 등록되어 있는 함수이다.

 

- JpaMain.java

Member member = new Member();
member.setUsername("관리자1");
member.setAge(10);
em.persist(member);

Member member1 = new Member();
member1.setUsername("관리자2");
member1.setAge(20);
em.persist(member1);

em.flush();
em.clear();

String query = "select function('group_concat', m.username) From Member m";
List<String> result = em.createQuery(query, String.class)
	.getResultList();
for (String s : result){
	System.out.println("s = " + s);
}

- Hibernate SQL

Hibernate: 
    /* select
        function('group_concat',
        m.username) 
    From
        Member m */ select
            group_concat(member0_.username) as col_0_0_ 
        from
            Member member0_
s = 관리자1,관리자2 /*group_concat 함수 내부 기능으로 , 기호를 통해 문자열이 합쳐졌다.*/

 

* 참고

위의 코드에서 select function('group_concat', m.username) From Member m 와 같이 사용자 정의 함수를 사용할 수 도 있지만 UnInject Language/Reference 를 이용하여 에디터에서 언어 참조 기능을 해제한 후 아래와 같이 코드를 작성해도 정상적으로 코드가 잘 작동하는 것을 확인할 수 있다

-> select group_concat(m.username) From Member m

/* 애초에 Hibernate 자체에서 위와 같은 문법을 지원하기 때문에 언어 참조 기능에서 참조중인 언어를 hql, 즉 Hibernate QL 로 바꿔줘도 사용자 정의 함수가 정상적으로 잘 작동하는 것을 확인할 수 있다. */

'JPA' 카테고리의 다른 글

JPQL - JPQL 페치 조인(1)  (0) 2020.11.28
JPQL - 경로 표현식  (0) 2020.11.28
JPQL - JPQL 기본(9)  (0) 2020.11.24
JPQL - JPQL 기본(8)  (0) 2020.11.24
JPQL - JPQL 기본(7)  (0) 2020.11.23