将条件查询与休眠一起使用时,如何将条件“或”在一起?


79

我正在尝试使用休眠条件查询在三个字段上执行基本的“或”操作。

class Whatever{
 string name;
 string address;
 string phoneNumber;
}

我想建立一个条件查询,其中我的搜索字符串可以匹配“名称”或“地址”或“ phoneNumber”。

Answers:


133

您要使用Restrictions.disjuntion()。像这样

session.createCriteria(Whatever.class)
    .add(Restrictions.disjunction()
        .add(Restrictions.eq("name", queryString))
        .add(Restrictions.eq("address", queryString))
        .add(Restrictions.eq("phoneNumber", queryString))
    );

请在此处查看Hibernate文档。


太完美了,谢谢!我终于在网上找到了一个示例,但很高兴它在这里供将来参考。
ScArcher2

8
如果我要(name = x AND address = y) OR (phoneNumber = z)怎么办?
凯文·梅雷迪斯

71

假设您要进行休眠会话,则应执行以下操作:

Criteria c = session.createCriteria(Whatever.class);
Disjunction or = Restrictions.disjunction();
or.add(Restrictions.eq("name",searchString));
or.add(Restrictions.eq("address",searchString));
or.add(Restrictions.eq("phoneNumber",searchString));
c.add(or);

4
我喜欢创建Disjunction并将其命名为or的语法。它比其他解决方案更具可读性。
ScArcher2

这很棒:)也同意@ ScArcher2,它非常易读,使我不得不更容易理解的更复杂的示例。
达斯汀·延森2015年

12
    //Expression :  (c1 AND c2) OR (c3)      


     Criteria criteria = session.createCriteria(Employee.class);

      Criterion c1 = Restrictions.like("name", "%e%");
      Criterion c2 = Restrictions.ge("salary", 10000.00);
      Criterion c3 = Restrictions.like("name", "%YYY%");
      Criterion c4 = Restrictions.or(Restrictions.and(c1, c2), c3);
      criteria.add(c4);

//(c1 OR c2)AND c3或任何复杂的表达式都可以做同样的事情。


6
//Expression :  (c1 AND c2) OR (c3)      


 Criteria criteria = session.createCriteria(Employee.class);

  Criterion c1 = Restrictions.like("name", "%e%");
  Criterion c2 = Restrictions.ge("salary", 10000.00);
  Criterion c3 = Restrictions.like("name", "%YYY%");
  Criterion c4 = Restrictions.or(Restrictions.and(c1, c2), c3);
  criteria.add(c4);

  //Same thing can be done for (c1 OR c2) AND c3, or any complex expression.

3

万一有人为NHibernate遇到同样的问题,以防万一,

ICriteria c = session.CreateCriteria(typeof (Whatever))
    .Add(Expression.Disjunction()
        .Add(Expression.Eq("name", searchString))
        .Add(Expression.Eq("address", searchString))
        .Add(Expression.Eq("phoneNumber", searchString)));

1

可以使用或/并使用析取在不同级别的查询中应用条件

Criteria query = getCriteria("ENTITY_NAME");
query.add(Restrictions.ne("column Name", current _value));

Disjunction disjunction = Restrictions.disjunction();

if (param_1 != null)
    disjunction.add(Restrictions.or(Restrictions.eq("column Name", param1)));

if (param_2 != null)
    disjunction.add(Restrictions.or(Restrictions.eq("column Name", param_2)));

if (param_3 != null)
    disjunction.add(Restrictions.or(Restrictions.eq("column Name", param_3)));
if (param_4 != null && param_5 != null)
    disjunction.add(Restrictions.or(Restrictions.and(Restrictions.eq("column Name", param_4 ), Restrictions.eq("column Name", param_5 ))));

if (disjunction.conditions() != null && disjunction.conditions().iterator().hasNext())
    query.add(Restrictions.and(disjunction));

return query.list();

是否有可能为所有未在数据库中找到的元素获取空值?
提琴

它是一致的:返回包含所有结果的列表,无论是否有结果。
Tiago Medici

1

这对我来说,对于OR条件是起作用的,对于IN条件而不是在此讨论中投票最多的答案:

criteria.add( Restrictions.or(
                    Restrictions.eq(ch.getPath(ch.propertyResolver().getXXXX()), "OR_STRING"),
                        Restrictions.in(ch.getPath(ch.propertyResolver().getYYYY()), new String[]{"AA","BB","CC"})
                    ));

结果查询:

  and (
            this_.XXXX=? 
            or this_.YYYY in (
                ?, ?, ?
            )
        ) 

1

如果有人使用CriteriaQuery而不是Criteria,则可以将所有表达式放在Predicate列表中,并按谓词大小放置OR,如下所示:

List<Predicate> predicates = new ArrayList<>();
if (...) {
  predicates.add(...);
}

criteriaQuery.where(cb.or(predicates.toArray(new Predicate[predicates.size()])));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.