Конструктор API критериев гибернации Spring передает параметр списка в функцию

#spring #spring-boot #hibernate #jpa #hibernate-criteria

#spring #spring-boot #спящий режим #jpa #hibernate-критерии

Вопрос:

Я пытаюсь реализовать полнотекстовый поиск MySQL внутри Criteria API Builder, и я застрял с передачей списка из нескольких столбцов в пользовательской функции.

Пользовательский диалект MySQL для включения СОПОСТАВЛЕНИЯ С функцией:

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

public class CustomMySQL5Dialect extends MySQL5Dialect {

    public CustomMySQL5Dialect() {
        super();
        registerFunction("match", new SQLFunctionTemplate(StandardBasicTypes.DOUBLE, "match(?1) against (?2 in boolean mode)"));
    }
}
 

Часть обслуживания клиентов для построения запроса:

 Specification.where((root, query, cb) -> {
    Expression<Double> match = cb.function(
        "match", 
        Double.class,
        root.get(Customer_.FIRST_NAME),
        cb.literal("mySearchTerm")
    );
    return cb.greaterThan(match, 0.);
});
 

Но теперь я хотел бы расширить полнотекстовый поиск для поиска по нескольким столбцам. Окончательный SQL должен выглядеть так:

 SELECT * FROM customer WHERE MATCH (first_name,last_name) AGAINST ('mysearchterm' IN BOOLEAN MODE) > 0.0 
 

Итак, кто-нибудь знает, как передать список имен столбцов для 1-го параметра.

Ответ №1:

 public class MariaDB10Dialect extends org.hibernate.dialect.MariaDB10Dialect {

    public MariaDB10Dialect() {
        registerFunction("match", new SQLFunction() {

            @Override
            public boolean hasArguments() {
                return true;
            }

            @Override
            public boolean hasParenthesesIfNoArguments() {
                return false;
            }

            @Override
            public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException {
                return StandardBasicTypes.DOUBLE;
            }

            @Override
            public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor factory) throws QueryException {
                StringBuilder sb = new StringBuilder("match(");
                int i=0;
                for (i=0; i<arguments.size()-1; i  ) {
                    if (i>0)
                        sb.append(", ");
                    sb.append(arguments.get(i));
                }
                sb.append(") against (").append(arguments.get(i)).append(")");
                return sb.toString();
            }
        });
    }

}