与关联对象的条件查询

问题描述:

我一直在努力解决这个Hibernate查询问题,我希望我可以在正确的方向上轻推。与关联对象的条件查询

我有一个名为FlashCard的对象,它具有名为Tags的关联对象。 FlashCard可以有一个或多个标签(有点像*问题可以被分配多个标签)。

我正在尝试使用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的代码示例避免的。如果它会有帮助,我会很乐意发布它们。

任何帮助最受赞赏。谢谢!

看看这篇文章,它解释了如何使用HQL与多对多的关系。

http://www.sergiy.ca/how-to-write-many-to-many-search-queries-in-mysql-and-hibernate/

+0

非常感谢。那篇文章是一个很大的帮助。 – Justin 2011-05-11 15:13:58