database

Querydsl 방언 사용하기

MIN우 2024. 2. 12. 15:56
728x90

Dialect

JPA를 사용하면 데이터베이스 문법을 잘 알지 못해도 hibernate에 의해 설정한 데이터베이스의 쿼리로 바꿔준다.

 

SQL,JPQL은 문자열인 반면 QUERYDSL을 사용하게 되면 java코드로 쿼리를 작성할 수 있게되고 컴파일 시점에 문법오류

를 확인할 수 있다는 큰 장점이 있다.

 

application.yml에 사용하는 DB의 dialect가 설정되어있다.

spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect

FullText Search는 Dialect에 등록된 함수가 아니였기 때문에 querydsl 에서 사용할 수 없기 떄문에 별도로

커스텀해줘야한다.

 

application.yml 설정

  jpa:
    show-sql: true
    hibernate:
      ddl-auto: create
    properties:
      hibernate:
        dialect: com.example.foodlog.global.config.CustomMySQLDialect
        format_sql: true
        default_batch_fetch_size: 1000

설정하기

package com.example.foodlog.global.config;

import org.hibernate.dialect.MySQL8Dialect;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.type.StandardBasicTypes;

public class CustomMySQLDialect extends MySQL8Dialect {

    /**
     * querydsl에서는 해당함수를 제공하지않기때문에 custom해서 mathch 함수 사용 시 해당 쿼리가 나가도록 설정
     */
    public CustomMySQLDialect() {
        super();
        registerFunction("match", new SQLFunctionTemplate(StandardBasicTypes.DOUBLE, "MATCH(?1) AGAINST (?2 IN NATURAL LANGUAGE MODE)"));
        registerFunction("matchs", new SQLFunctionTemplate(StandardBasicTypes.DOUBLE, "MATCH(?1, ?2) AGAINST (?3 IN NATURAL LANGUAGE MODE)"));
    }
}

사용하기

    private BooleanExpression searchWordContains(String keyword) {
        if (StringUtils.isBlank(keyword)) {
            return null;
        }

        return Expressions.numberTemplate(Double.class,
                "function('matchs', {0}, {1}, {2})", food.category, food.restaurant, keyword).gt(0);
    }

만약 키워드가 해당 필드에 존재하지 않으면 0을 반환하고, 존재한다면 scoring 된 값을 뱉어줌으로 0보다 크면 반환을 해준다.

 

728x90