2012-02-01 101 views
3

我想转换原生SQL查询以使用JPA 2.0中的Criteria API。我在Google上发现了很多Criteria API示例,但我很难将所有这些部分放在一起。我希望一个更有经验的人能够帮助我。原生查询如下所示:联盟所有和与JPA CriteriaBuilder结合

select 
    sum(amount) from firstTable, secondTable 
     where firstTable.id = secondTable.id 
      and amount <> 0 
      and firstTable.id = ? 
union all 
select 
    sum(amount) from firstTable, thirdTable 
     where firstTable.id = thirdTable.id 
      and amount <> 0 
      and firstTable.id = ? 

原始查询结果集正在返回一个BigDecimal对象列表。

谢谢!

回答

6

JPA不支持UNION,使用本机SQL查询或执行两个查询。

+1

你知道为什么不支持UNION吗? – santedicola 2012-10-26 10:09:22

+2

EclipseLink支持UNION http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#UNION – James 2012-10-31 14:09:32

2

不好意思,下面的例子不是union,而是连接。

我会考虑使用具有多个根的查询。

这里是Hiberante开发人员指南的一个exerpt,代码与JPA 2.0兼容。

标准查询可能会定义多个根,其效果是在新添加的根与其他根之间创建笛卡尔积。下面是一个例子匹配所有单身男女都单身女性:

CriteriaQuery query = builder.createQuery(); 
Root<Person> men = query.from(Person.class); 
Root<Person> women = query.from(Person.class); 
Predicate menRestriction = builder.and(
     builder.equal(men.get(Person_.gender), Gender.MALE), 
     builder.equal(men.get(Person_.relationshipStatus), RelationshipStatus.SINGLE) 
); 
Predicate womenRestriction = builder.and(
     builder.equal(women.get(Person_.gender), Gender.FEMALE), 
     builder.equal(women.get(Person_.relationshipStatus), RelationshipStatus.SINGLE) 
); 
query.where(builder.and(menRestriction, womenRestriction)) 
+0

select子句在这里看起来如何?我正在使用criteriaBuilder.construct来提取选定的列。 – user613114 2016-08-08 15:06:17

+0

to @ user613114:我好几年没有使用过ORM和Java,但我会尽力回答。 上面的例子会给你单身男人和单身女人的所有可能的组合。 SQL查询将如下所示: 从人员a,人员b选择a.name b.name其中a.gender ='male'和b.gender ='female'并且a。status = single和b.status = single – Alex 2017-02-28 17:31:35

1

如果需要UNION ALL,那么两个实体的候选人在我的脑海申请继承他们。

0

正如Marcin指出的那样,继承是可能的,至少在特殊情况下。

如果您可以使用TABLE_PER_CLASS继承策略(可选地,可能在hibernate中提供,但在那里存在限制 - 您不能使用IDENTITY和AUTO),并且如果查询中存在的字段具有在两个实体中都有相同的名称,那么你可以通过查询父实体来统一两个实体。

举例来说,如果实体类儿童从实体类父扩展均具有“name”字段,查询将是:

从父p选择p.name

只选择父实体的名称添加条件与TYPE。

从父p选择p.name其中TYPE(P)=父

如果修改实体继承一个从另一个是不合适的,您可以创建特殊的人(有继承,事业)此查询,因为可以为同一个表创建多个实体。但是你可能不会觉得这种努力是合理的。