我一直在努力解決這個Hibernate查詢問題,我希望我可以在正確的方向上輕推。與關聯對象的條件查詢
我有一個名爲FlashCard的對象,它具有名爲Tags的關聯對象。 FlashCard可以有一個或多個標籤(有點像StackOverflow問題可以被分配多個標籤)。
我正在嘗試使用Hibernate來返回分配了特定標籤的所有FlashCards。例如,我想查詢所有具有「tag2」和「tag4」的FlashCards。
我試過到目前爲止與準則的查詢,查詢示例和HQL接近這一切,沒有運氣。
這裏的數據庫是什麼樣子: 的mysql> SELECT * FROM燒錄卡;
+--------------+------------+----------+
| FLASHCARD_ID | QUESTION | ANSWER |
+--------------+------------+----------+
| 1 | Question 1 | Answer 1 |
| 2 | Question 2 | Answer 2 |
| 3 | Question 3 | Answer 3 |
| 4 | Question 4 | Answer 4 |
+--------------+------------+----------+
4 rows in set (0.00 sec)
mysql> select * from tag;
+--------+------+
| TAG_ID | NAME |
+--------+------+
| 1 | tag1 |
| 3 | tag2 |
| 2 | tag3 |
| 4 | tag4 |
| 5 | tag5 |
+--------+------+
5 rows in set (0.00 sec)
mysql> select * from flashcard_tags;
+--------+--------------+
| TAG_ID | FLASHCARD_ID |
+--------+--------------+
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 3 | 2 |
| 4 | 2 |
| 5 | 2 |
| 3 | 3 |
+--------+--------------+
7 rows in set (0.00 sec)
使用上面的數據,您可以看到只有FlashCard的1和2具有BOTH「tag2」和「tag4」。
我創建了一個earlier post只是爲了確認哪些SQL(實際SQL)將返回結果和這裏的兩個工作例子。
示例1工作SQL查詢:
SELECT f.*
FROM (
SELECT flashcard_id
FROM tags t
JOIN flashcard_tags ft
ON ft.tag_id = t.tag_id
WHERE t.name IN ('tag2', 'tag4')
GROUP BY
flashcard_id
HAVING COUNT(*) = 2
) ft
JOIN flashcard f
ON f.flashcard_id = ft.flashcard_id
實例工作SQL查詢的2:
SELECT f.*
FROM flashcard f
INNER JOIN flashcard_tags ft1 ON f.FLASHCARD_ID = ft1.FLASHCARD_ID
INNER JOIN tag t1 ON ft1.TAG_ID = t1.TAG_ID AND t1.NAME = 'tag2'
INNER JOIN flashcard_tags ft2 ON f.FLASHCARD_ID = ft2.FLASHCARD_ID
INNER JOIN tag t2 ON ft2.TAG_ID = t2.TAG_ID AND t2.NAME = 'tag4'
下面是Hibernate的映射是什麼樣子:
<hibernate-mapping>
<class name="org.robbins.flashcards.model.FlashCard" table="FLASHCARD">
<id name="flashCardId" type="int" column="FLASHCARD_ID">
<meta attribute="scope-set">public</meta>
<generator class="native" />
</id>
<property name="question" type="string">
<meta attribute="use-in-tostring">true</meta>
<column name="QUESTION" not-null="true" unique="true" />
</property>
<property name="answer" type="text">
<meta attribute="use-in-tostring">true</meta>
<column name="ANSWER" not-null="true" />
</property>
<set name="tags" table="FLASHCARD_TAGS">
<meta attribute="field-description">Tags for this FlashCard</meta>
<key column="FLASHCARD_ID" />
<many-to-many class="org.robbins.flashcards.model.Tag"
column="TAG_ID" />
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="org.robbins.flashcards.model.Tag" table="TAG">
<id name="tagId" type="int" column="TAG_ID">
<meta attribute="scope-set">public</meta>
<generator class="native" />
</id>
<property name="name" type="string">
<meta attribute="use-in-tostring">true</meta>
<column name="NAME" not-null="true" unique="true" />
</property>
<set name="flashcards" table="FLASHCARD_TAGS" inverse="true">
<meta attribute="field-description">FlashCards for this Tag</meta>
<key column="TAG_ID" />
<many-to-many class="org.robbins.flashcards.model.FlashCard"
column="FLASHCARD_ID" />
</set>
</class>
</hibernate-mapping>
最後,以下是生成的FlashCard類的摘錄,您可以在其中看到關聯的標記:
public class FlashCard implements java.io.Serializable {
private int flashCardId;
private String question;
private String answer;
private Set<Tag> tags = new HashSet<Tag>(0);
}
我遇到了創建會檢索相同結果的Hibernate代碼的問題。我嘗試了一個Criteria查詢,但得知它們不支持SQL「having」子句或在From子句中使用「子查詢」作爲SQL示例#1。
我試圖通過實施例查詢(通過在該過連接有兩個標籤的對象閃卡的例子),並在所有接收到的任何結果。
我也試圖尋找到HQL但讀「即HQL子查詢只能出現在select或者where子句。」
而不是讓這個職位不再,我現在就可以發佈我的失敗Hibernate的代碼示例避免的。如果它會有幫助,我會很樂意發佈它們。
任何幫助最受讚賞。謝謝!
非常感謝。那篇文章是一個很大的幫助。 – Justin 2011-05-11 15:13:58