【问题标题】:Criteria API in Hibernate, multiple restrictions for same column in joining tableHibernate中的Criteria API,连接表中同一列的多个限制
【发布时间】:2016-02-22 09:41:11
【问题描述】:

我有如下表personpersonDoc

person :

personNo
dateofBirth
firstname
LastName
MiddleName
salutationCode

personDoc :

personNo
doctype
documentNo

我必须搜索姓名 = "John" and (doctype = "passport" and documentNo = "XXXX') and (doctype = "Driving license" and documentNo = "YYYY")的人

我正在使用条件 API 进行搜索。

我已经使用别名加入了personpersondoc 表。

如何多次添加限制(针对同一个表和列)?

注意:对于更多场景,我需要搜索:

名字如“John”和(doctype = "passport" and documentNo = "XXXX') 或 (doctype = "Driving license" and documentNo = "YYYY")的人。

【问题讨论】:

  • @DieterMeemken Criteria c = getSession().createCriteria(PersonWrapper.class,"rel");标准 firstName = Restrictions.eq("rel.firstName",fName); c.add(名字); for(PersonDocWraper pDocWrapper :argperSonWrapper.getRelationshipDocumentWrappers().values()) { aliasName = "pDOC"+pDocWrapper .getDocumentTypeCode(); c.createAlias("pDocWrapper ", aliasName, JoinType.INNER_JOIN); c.add(Restrictions.eq(aliasName.concat(".documentTypeCode"), pDocWrapper.getDocumentTypeCode())); c.add(Restrictions.eq(aliasName.concat(".documentTypeValue"), pDocWrapper.getDocumentValue())); } returnList = c.list();

标签: java hibernate hibernate-criteria


【解决方案1】:

使用 Criteria 创建以下查询:

名字像“John”和(doctype =“passport”和documentNo的人 = "XXXX') 或 (doctype = "驾驶执照" and documentNo = "YYYY")。

你可以试试Criteria's Disjunction and Conjunction feature

如果不了解PersonPersonDoc 表是如何使用entity classes 映射的,就很难建立准确的标准。但我希望下面的例子能给你一些提示,你可以做到。

Disjunction disjunction = Restrictions.disjunction(); //OR condition

Conjunction conjunction1  = Restrictions.conjunction(); //AND condition
conjunction1.add(Restrictions.eq("doc.doctype", "passport"));
conjunction1.add(Restrictions.eq("doc.documentNo", "XXXX"));

Conjunction conjunction2  = Restrictions.conjunction(); //AND condition
conjunction2.add(Restrictions.eq("doc.doctype", "Driving License"));
conjunction2.add(Restrictions.eq("doc.documentNo", "YYYY"));

disjunction.add(conjunction1);
disjunction.add(conjunction2);

并且这种析取可以用于标准构建(例如):

session.createCriteria(Person.class, "p").createAlias(.., "doc").
add(Restrictions.and(Restrictions.like("p.name", "John"),   disjunction)).   
setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

添加了setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 以确保它只返回不同的Person 实体。

请注意,我们也可以使用 Restrictions.andRestrictions.or 实现相同的效果。

如果这没有帮助,请发布与 PersonPersonDoc 表相关的实体。

【讨论】:

  • 非常感谢您的输入。会尝试让你知道。
【解决方案2】:

您可以通过以下方式实现:

Root<Person> r = cq.from(Person.class);
Root<PersonDoc> p = cq.from(PersonDoc.class);
cq.where(
   cb.and(
      cb.equal(r.get(Person_.name), "John"),     
      cb.or(
        cb.and(
           cb.equal(p.get(PersonDoc_.doctype), "passport"), 
           cb.equal(p.get(PersonDoc_.documentNo), "XXXX")
        ), 
        cb.and(
           cb.equal(p.get(PersonDoc_.doctype), "driverLicense"), 
           cb.equal(p.get(PersonDoc_.documentNo), "XXXX")
        )
      ),  
      cb.equal(p.get(PersonDoc_.person), r)
   );

【讨论】:

  • 我们没有使用 JPA,我们使用的是休眠,我正在尝试 Criteria API,因为它涉及动态搜索。
  • 然后将类型安全 jpa 的条件调用替换为纯休眠的非类型安全调用。方法是相同的:不是连接而是多个根。以及正确合并“and”和“or”语句
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
  • 2015-03-04
  • 2012-08-18
  • 2011-01-16
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
相关资源
最近更新 更多