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