項目中遇到的HQL查詢問題
問題描寫敘述:
目的:想要查詢出全部最新版本號的組件
說明:組件:版本號 =1:n關系 ,假設這個組件僅僅有一個版本號也要可以查出來。
項目中使用的是內存數據庫,無法看到表結構,這裏的樣例僅僅用於模擬。
也即是:
- 最初的數據是這種。
- 想要的結果是這種。
- 最初的設想是這種。
select component from Component component where component.owner=:userId andcomponent.componentId.version.versionString
in (select Max(c.componentId .version.versionString) from Component c where component.owner=:userId group by c.componentId.name )
不足:發現對於同一個組件,它的不同版本號都能出現。這個bug我沒發現,後來他們發現了。。
4. 經歷的挫折
select c2.id,c2.name,c2.user,c2.categoryname, Max(c2.version) version from component c2 where c2.user="tan" group by c2.name;
這樣在數據庫中查詢時是沒有問題的,關鍵是在項目中通常是面向對象的,假設在項目中改為例如以下:
select c.componentId.name,Max(c.componnetId.version.versionString) from component c
where c.owner=:userId group by c.componentId.name
發現能正常顯示,可是當在前面增加其他字段(比方:c.image)它就會報錯了,假設想讓它不報錯就得以它來分組,可是在實際情況中絕不可能這麽做,由於組件同樣可是版本號是不同的。
5. 終於的解決方式
上面的對象查詢中僅僅用一個組件名並不能唯一確定一個相應版本號的組件,那麽怎樣來唯一確定呢?
我想了非常久也沒有想到解決的方法。後來在我的組長的幫助下,終於攻克了這個問題。
既然一個字段不能唯一確定,為什麽不用2個字段進行唯一確定呢?
CONCAT(s1,s2) 連接連個字符串 字符串函數 JPQHQL HQL CONCAT([對象屬性],[對象屬性])
使用CONCAT函數就行使得組件名和版本號後捆綁在一起。就行唯一確定最新版本號的組件。
終於解決,代碼例如以下:
select component from Component component where component.owner=:userId and CONCAT(component.componentId.name,component.componentId.version.versionString)
in (select CONCAT(c.componentId.name,Max(c.componentId.version.versionString)) from Component c group by c.componentId.name )
上面的某些情況下會出現bug,比方ComponentName=AB,Version=CD,而另外一個ComponentName=A,Version=BCD,這樣一來拼接的結果都是ABCD,這樣就會出現反復的問題。
【怎樣解決?】—-可以使用括號括起來分別進行條件的推斷
select component from Component component where component.isApproved=true and component.categoryName = :categoryName and (component.componentId.name,component.componentId.version.versionString) in (select c.componentId.name,Max(c.componentId.version.versionString) from Component c group by c.componentId.name )
參考網址:http://www.cnblogs.com/caotang/archive/2011/01/18/1937932.html
6.反思
遇到問題,一定要敢於去想,敢於往不同的層面去想並不斷的嘗試去解決它。切記不可以固執己見。停在原地打轉,柳暗花明往往就在於思想越界的一瞬間。
項目中遇到的HQL查詢問題