스프링데이터 + JPA/QueryDSL

26. SQL 함수 호출

sdafdq 2023. 12. 2. 17:05

QueryDSL로 DB의 함수를 호출하는 쿼리를 만드는 것이 가능하다.

 

@Test
public void sqlFunction(){
    List<String> result = query.select(Expressions.stringTemplate(
                    "function('replace', {0}, {1}, {2})",
                    m.username, "member", "M"
            )).from(m)
            .fetch();

    for (String s : result) {
        System.out.println("s = " + s);
    }
}
Expressions.stringTemplate(
    "function('DB함수명', {0}, {1} ....)",
    0번째인자, 1번째인자 ....
)

이렇게 쓴다.

 

표현식.문자형템플릿(function('함수명', 인자들..), 인자들.. )

저 DB의 함수가 반환하는 값에 따라 stringTemplate라고 할 지, numberTemplate라고 할 지 다르다.

 

/* select
    function('replace', member1.username, ?1, ?2) 
from
    Member member1 */ select
        replace(m1_0.username, ?, ?) 
    from
        member m1_0

jpql보면 함수 호출을 하며 인자를 넣는다.

DB쿼리는 아예 함수를 호출해 버린다.

 

저거는 이제 ANSI표준에 등록된 기본 함수중 하나이고, 만약 DB관리자가 만든 커스텀 함수를 사용하고 싶다면, 

 

방언클래스, 지금같은 경우는 H2니가 H2Dialect라는 클래스를 상속받아 registerFunction 하면서 등록하면서 썼어야 했는데, 하이버네이트6 오면서 그냥 쓸 수 있다. 여기서 딱히 뭘 하지 않아도 된다.

 

https://qwefdg3.tistory.com/774

 

s = M1
s = M2
s = M3
s = M4

잘 나옴.

 

 

 

그런데, 저런 표준적인 함수들은 QueryDSL에서 어느정도 내장을 해서 제공해 주고 있다.

 

예를 들어

@Test
public void sqlFunction2(){
    List<String> result = query.select(Expressions.stringTemplate("function('lower', {0})", m.username)).from(m)
    					.fetch();

    for (String s : result) {
        System.out.println("s = " + s);
    }
}
/* select
    function('lower', member1.username) 
from
    Member member1 */ select
        lower(m1_0.username) 
    from
        member m1_0

 

이렇게 썼다면

 

@Test
public void sqlFunction2(){
    List<String> result = query.select(m.username.lower()).from(m).fetch();

    for (String s : result) {
        System.out.println("s = " + s);
    }
}
/* select
    lower(member1.username) 
from
    Member member1 */ select
        lower(m1_0.username) 
    from
        member m1_0

이렇게.

 

다 쿼리메소드로 지원해 준다.

나가는 쿼리도 완전히 같다.

 

결과도 문제없다. 둘 다 lower케이스로 변환되어 나온다.