반응형

Hibernate는 특정 데이터베이스에 종속되지 않고 객체지향스럽게 사용할 수 있도록 추상화해준다. 때문에 특정 DB에 종속된 함수(예를 들면 mysql의 group_concat)는 제공하지 않는다.

되도록 DB 확장성을 위해 특정 DB에 종속된 기능 사용은 고려해볼 필요가 있지만, 그 기능이 비즈니스 요구사항을 풀기에 적절하고 필요하다고 판단된다면 확장성에 너무 얽매일 필요는 없다고 생각한다. 물론 DB를 변경할 예정이라면 어차피 바꿔야 하니 사용하지 말자.

어쨌든 특정 데이터베이스에서만 제공하는 함수, 여기에서는 mysql group_concat을 사용하기 위해 Dialect를 확장하여 커스텀 SQL 함수를 등록해보자.


CustomMysqlDialect 클래스 생성

import org.hibernate.dialect.MySQL5Dialect;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.StandardBasicTypes;

public class CustomMysqlDialect extends MySQL5Dialect {
    public CustomMysqlDialect() {
        super();
        registerFunction("group_concat",
                new StandardSQLFunction("group_concat", StandardBasicTypes.STRING));
    }
}

application.yml에 CustomMysqlDialect 연결

spring:
  jpa:
    database-platform: net.huray.platform.config.CustomMysqlDialect
  ...

이제 mysql의 group_concat을 사용하기 위한 기본 설정은 끝났다.

사용 방법에 대해서는 아래 참고 자료를 확인하길 바란다.


후기

알고 보니 Dialect을 확장하지 않고도 내가 원하는 group_concat과 유사한 효과를 내는 방법을 알게 되었다.

나는 아직 JPA 뉴비인지라 Entity 연관 관계를 통해 데이터를 다루는 게 익숙하지 않았다. 내가 원했던 것은 1:N 그룹핑한 후 페이징 적용이었는데 JPA 연관관계를 맺는 것으로도 충분히 가능했다. 실행계획을 자세히 살펴보지 않았지만 연관 관계를 맺어 가져오는 방법도 성능 이슈가 크지 않는 듯 했다.

Dialect을 확장하지 않고도 가능한 방법이 있다면 굳이 DB에 종속된 group_concat선택할 이유가 없기 때문에 위 설정은 rollback했다. 내가 선택한 방법이 최선이라는 보장은 없기 때문에 코드리뷰가 중요한 것 같다.


참고 자료

https://cheese10yun.github.io/jpa-query-dsl-group-concat/

https://stackoverflow.com/questions/12346845/registering-a-sql-function-with-jpa-and-hibernate

반응형