2012-02-01 99 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)=父

如果修改實體繼承一個從另一個是不合適的,您可以創建特殊的人(有繼承,事業)此查詢,因爲可以爲同一個表創建多個實體。但是你可能不會覺得這種努力是合理的。