【问题标题】:JPA Criteria api with CONTAINS function具有 CONTAINS 功能的 JPA Criteria api
【发布时间】:2013-08-31 13:16:38
【问题描述】:

我正在尝试使用 CONTAINS 函数(MS SQL)创建 Criteria API 查询:

select * from com.t_person where contains(last_name,'xxx')

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
Root<Person> root = cq.from(Person.class);

Expression<Boolean> function = cb.function("CONTAINS", Boolean.class, 
root.<String>get("lastName"),cb.parameter(String.class, "containsCondition"));
cq.where(function);
TypedQuery<Person> query = em.createQuery(cq);
query.setParameter("containsCondition", lastName);
return query.getResultList();

但是遇到异常: org.hibernate.hql.internal.ast.QuerySyntaxException:意外的 AST 节点:

有什么帮助吗?

【问题讨论】:

  • 你使用的是什么版本的休眠?
  • 与 JBOSS 捆绑的版本。完全不使用 Hibernate API 只是 JPA。

标签: java jpa


【解决方案1】:

如果你想坚持使用CONTAINS,它应该是这样的:

//Get criteria builder
CriteriaBuilder cb = em.getCriteriaBuilder();
//Create the CriteriaQuery for Person object
CriteriaQuery<Person> query = cb.createQuery(Person.class);

//From clause
Root<Person> personRoot = query.from(Person.class);

//Where clause
query.where(
    cb.function(
        "CONTAINS", Boolean.class, 
        //assuming 'lastName' is the property on the Person Java object that is mapped to the last_name column on the Person table.
        personRoot.<String>get("lastName"), 
        //Add a named parameter called containsCondition
        cb.parameter(String.class, "containsCondition")));

TypedQuery<Person> tq = em.createQuery(query);
tq.setParameter("containsCondition", "%näh%");
List<Person> people = tq.getResultList();

您的问题中似乎缺少您的一些代码,所以我在这个 sn-p 中做了一些假设。

【讨论】:

  • 我得到了 QuerySyntaxException:意外的 AST 节点:(在第 1 行附近,第 109 列 [从 sk.insdata.cbn.business.client.entities.Person 中选择 generateAlias0 作为 generatedAlias0,其中 CONTAINS(generatedAlias0.lastName, :参数0)]
  • @petersaly 检查我的编辑...我认为你实际上也需要一个 cb.equal 。
  • 我最初尝试过的:org.hibernate.exception.SQLGrammarException: '=' 附近的语法不正确
  • 如果您只是在您的数据库上运行该查询:select generatedAlias0 from sk.insdata.cbn.business.client.entities.Person as generatedAlias0 where CONTAINS(generatedAlias0.lastName, :param0) 是否有效?
  • 是的,运行原生查询有效:select * from com.t_person where contains(last_name,'%saly%')
【解决方案2】:

您可以尝试使用 CriteriaBuilder like 函数而不是 CONTAINS 函数:

//Get criteria builder
CriteriaBuilder cb = em.getCriteriaBuilder();
//Create the CriteriaQuery for Person object
CriteriaQuery<Person> query = cb.createQuery(Person.class);

//From clause
Root<Person> personRoot = query.from(Person.class);

//Where clause
query.where(
    //Like predicate
    cb.like(
        //assuming 'lastName' is the property on the Person Java object that is mapped to the last_name column on the Person table.
        personRoot.<String>get("lastName"),
        //Add a named parameter called likeCondition
        cb.parameter(String.class, "likeCondition")));

TypedQuery<Person> tq = em.createQuery(query);
tq.setParameter("likeCondition", "%Doe%");
List<Person> people = tq.getResultList();

这应该会产生类似于以下内容的查询:

select p from PERSON p where p.last_name like '%Doe%';

【讨论】:

  • 谢谢。但我希望能够进行高级搜索,例如不区分重音的搜索(näh - 会找到 - nah)。
  • 根据我的经验,CriteriaBulider.like 非常有限。它只支持周围的通配符,即:%doe% 但不支持 %doe
猜你喜欢
  • 1970-01-01
  • 2013-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-19
  • 1970-01-01
相关资源
最近更新 更多