2011-08-30 35 views
2

這是什麼約定?例如說,我有以下的,其中一個項目投標只能在一個項目投標:我是否應該遍歷hibernate集合以查找實體或使用條件

public class Item { 
    @OneToMany(mappedBy="item", nullable="false" 
    Set<ItemBid> itemBids = new HashSet<ItemBid>() 
} 

如果我給出的項目投標人的名稱(存儲在ItemBid)應IA)啓動俱樂部使用俱樂部道具並迭代它的itemBids的集合,直到找到具有我想要的名稱的俱樂部,或者B)創建一個ItemBid道具,在標準或HQL中使用俱樂部和物品出價名稱。

我會認爲B)對於非常大的集合來說效率最高,那麼這對於從大型集合中檢索非常特定的項目是否是標準?如果是這樣,我可以有一個總體原則,我應該使用這些集合的原因是什麼,以及我應該在什麼時候使用DAO/Criteria?

回答

3

是的,您應該直接查詢出價。下面是準則:

  • 如果你正在尋找一個具體的出價,使用查詢
  • 如果您如果要顯示給定項目的所有投標需要投標的一個子集,使用查詢
  • - 這取決於。如果出價數量相當小,則取物品並使用收藏。否則 - 直接查詢。

從OO透視你應該總是使用集合當然(優選具有在Item訪問出價收集findBy*()方法內部) - ,其也比較方便。但是,如果每件商品的出價數量很大,則(甚至是懶惰)加載的成本將很高,並且很快就會耗盡內存。這種方法也非常浪費。

2
  1. 你應該早點問自己這個問題:在你做映射的時候。 ORM的映射應該是一項智力工作,而不是將所有外鍵複製到雙方的屬性上。 (如果只是因爲YAGNI,但還有其他很多理由)

  2. 很可能,出價項目映射會更好,因爲單向(然後可能不是)。

  3. 在很多情況下,我們發現某些實體與幾乎固定數量的某些其他實體(他們可能被稱爲DDD說法中的「聚合」)緊密關聯。例如發票和發票項目。或者一個人和他的愛好列表。或者這篇文章的帖子和一組標籤。我們不希望給定發票中的項目數量會隨着時間的推移而增長,標籤的數量也不會增加。所以他們都是映射@OneToMany的好地方。另一方面,每個客戶的發票數量將會增加 - 所以我們只需從客戶映射一個單向的@ManyToOne發票 - 然後查詢。 (查詢沒有錯;它只是一個以存儲中立的方式描述你的需求的對象)。在實體中使用發現者 - 並非如此。從實際的角度來看,它將你的實體綁定到數據訪問層(DAO甚至JPA類),這會使得它們在許多用例(GWT)中不可用或者在分離時使用起來很棘手(你將不得不猜測哪些方法在外部工作會話)。從哲學的角度來看 - 它違反了單一責任原則,並將您的JPA實體變成了一種活躍的記錄想要的東西。

所以,我的回答是:

  • ,如果你需要一個出價,如果你想顯示給定項目的所有投標直接查詢,
  • - 獲取的項目,使用該集合。這不取決於每個項目的出價次數,因爲由JPA執行的查詢將與您可能執行的查詢相同。如果這種方法需要調整(就像在需要獲取大量項目並希望避免「N + 1選擇問題」的情況下),那麼有很多方法(聯合提取,提取提取,提示)來實現它沒有改變使用getBids()的代碼部分。

去想它最簡單的方法是:如果你認爲一些集合將永遠不會分頁顯示(像人的標籤後,發票項目,愛好),與@OneToMany和訪問作爲地圖它一個集合。