2009-12-27 73 views
1

我正在使用JPA來查看它是多麼有用,而不是使用直接的SQL,並且我今天意識到我的某列不正確。如何定義實際上不與另一個表通過鍵,但通過關鍵字相關的列

我有一個播放列表應用程序。每個播放列表都有一個標題和一個表示要包含的歌曲的關鍵字列表。

所以,我可能會有這一行,有三個關鍵字。 運動steady-beat_country hard_rock classic_rock

如果我添加了一首新歌曲,其中應用了這些關鍵字之一,我希望在選擇此播放列表時將其拉起。

我可以通過所有具有此關鍵字,並涉及與播放列表中的新歌曲的播放列表,但似乎是非常低效的,如果我有各自與許多播放幾個用戶,如果歌曲可以通過播放所有的用戶。

我很好奇,如果我只是做這在我的@Entity模型,這是寫在Scala

@transient 
var songs : java.util.List[Song] = new java.util.ArrayList[Song]() 

@OneToMany{val cascade=Array(CascadeType.ALL), val mappedBy="playlist"} 
var keywords : java.util.List[Snippet] = new java.util.ArrayList[Snippet]() 

然後,我可以只加載實際涉及到播放列表中的關鍵字,然後調用名爲可以通過關鍵字列表加載歌曲的查詢。

或者,有沒有辦法在JPA中定義像這樣的東西,所以我不必撥打額外的電話?

UPDATE:

今晚我測試這一點,但我想知道如果我可以建立我的命名查詢要做到這一點查詢,所以這將是這樣的:

SELECT Playlist p, Songs s WHERE p.user = :user AND s.keywords IN (p.keywords)

這段代碼有點有缺陷,因爲IN需要查看我如何在JPA中執行此操作,但可能需要將關鍵字存儲爲逗號分隔符,但我不確定如何將歌曲填入song物業爲playlist

回答

1

你的歌曲和關鍵詞之間有多對多的關係。
我相信你的查詢應該是select p from Playlist p, Songs s where p.user = :user and s.keywords member of p.keywords,雖然我不是100%確定你可以在兩個集合之間做一個member of操作。您可能必須使用子查詢來抓取所有的p.keywordsANY表達式才能做到這一點。有關更多信息,請參閱this article

在您回答之後,我意識到播放列表不是您從JPQL獲取的歌曲列表。您正嘗試在播放列表對象中設置字段。

如果您認爲JPA只是一個簡單的數據庫工作方式。你是不錯的。你無法真正做到我相信你用任何OO語言做的事情。您不能將字段定義爲查詢的結果。

但是,您可以做的是從播放列表的用戶,名稱和關鍵字中獲取播放列表定義。然後運行一個查詢查找帶有這些關鍵字的歌曲,然後在java中執行類似curPlaylist.addAll(queryResult); em.merge(curPlaylist);的操作。這假設你有你的瀑布當然設置正確。現在,當您從實體管理器中獲取播放列表時,您還將撤回播放列表。

如果您正在尋找更動態的內容,列表會自動更新,那麼您可以在每次需要符合播放列表條件的列表時運行查詢。

+0

謝謝你的迴應。我會看看我正在使用IN的成員,如下所示:http://download.oracle.com/docs/cd/E11035_01/kodo41/full/html/ejb3_langref.html#ejb3_langref_collection_dec,雖然這篇文章有錯誤,但是我的方法意味着我正在逐個檢查每個關鍵字。 – 2009-12-29 19:29:33