Kev*_*vin 5 full-text-search jpa eclipselink
我想使用JPA 使用MySQL的全文搜索功能,而不必使用本机查询.
我正在使用EclipseLink,它具有支持本机SQL命令的功能:FUNC.但是,帮助示例仅显示这与简单的MySQL函数一起使用.我尽最大努力使其与MATCH&AGAINST合作如下:
@PersistenceContext(name="test")
EntityManager em;
Query query = em.createQuery("SELECT person FROM People person WHERE FUNC('MATCH', person.name) FUNC('AGAINST', :searchTerm)");
...
query.getResultList();
Run Code Online (Sandbox Code Playgroud)
这给出了以下例外:
Caused by: NoViableAltException(32@[()* loopback of 822:9: (m= MULTIPLY right= arithmeticFactor | d= DIVIDE right= arithmeticFactor )*])
at org.eclipse.persistence.internal.libraries.antlr.runtime.DFA.noViableAlt(DFA.java:159)
at org.eclipse.persistence.internal.libraries.antlr.runtime.DFA.predict(DFA.java:116)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.arithmeticTerm(JPQLParser.java:4557)
... 120 more
Run Code Online (Sandbox Code Playgroud)
我对使用FUNC方法的其他替代方案持开放态度.
我正在使用EJB 3和EclipseLink 2.3.1.
改进了@Markus Barthlen的答案,适用于Hibernate.
public class MySQLDialectCustom extends MySQL5Dialect {
public MySQLDialect() {
super();
registerFunction("match", new SQLFunctionTemplate(StandardBasicTypes.DOUBLE,
"match(?1) against (?2 in boolean mode)"));
}
}
Run Code Online (Sandbox Code Playgroud)
并通过设置hibernate.dialect属性进行注册.
在JPQL中:
Query query = entityManager
.createQuery("select an from Animal an " +
"where an.type = :animalTypeNo " +
"and match(an.name, :animalName) > 0", Animal.class)
.setParameter("animalType", "Mammal")
.setParameter("animalName", "Tiger");
List<Animal> result = query.getResultList();
return result;
Run Code Online (Sandbox Code Playgroud)
或使用Criteria API:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Animal> criteriaQuery = criteriaBuilder.createQuery(Animal.class);
Root<Animal> root = criteriaQuery.from(Animal.class);
List<Predicate> predicates = new ArrayList<>();
Expression<Double> match = criteriaBuilder.function("match", Double.class, root.get("name"),
criteriaBuilder.parameter(String.class, "animalName"));
predicates.add(criteriaBuilder.equal(root.get("animalType"), "Mammal"));
predicates.add(criteriaBuilder.greaterThan(match, 0.));
criteriaQuery.where(predicates.toArray(new Predicate[]{}));
TypedQuery<Animal> query = entityManager.createQuery(criteriaQuery);
List<Animal> result = query.setParameter("animalName", "Tiger").getResultList();
return result;
Run Code Online (Sandbox Code Playgroud)
此博客文章中的更多详细信息:http://pavelmakhov.com/2016/09/jpa-custom-function
FUNC仅适用于普通打印功能,
即MATCH(arg1,arg2)
因为MATCH arg1 AGAINST arg2没有按照正常打印功能的方式打印,所以FUNC不能用来调用它.
EclipseLink ExpressionOperators确实支持这样的打印功能,因此您可以定义自己的ExpressionOperator,但ExpressionOperators目前仅通过EclipseLink Expression查询支持,而不是通过JPQL支持.您可以记录增强功能以在JPQL中获得操作员支持.
您还可以使用本机SQL查询.
| 归档时间: |
|
| 查看次数: |
9257 次 |
| 最近记录: |