首页 > 解决方案 > Spring Hibernate Criteria API Builder 将列表参数传递给函数

问题描述

我尝试在 Criteria API Builder 中实现 MySQL 全文搜索,但我坚持在自定义函数中传递多列列表。

自定义 MySQL 方言以启用 MATCH AGAINST 功能:

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 

那么,有谁知道如何传递第一个参数的列名列表。

标签: springspring-boothibernatejpahibernate-criteria

解决方案


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();
            }
        });
    }

}

推荐阅读