【问题标题】:Hibernate one to many retrieval休眠一对多检索
【发布时间】:2017-03-14 03:59:13
【问题描述】:

我有两张表,父母和孩子。我在这两个表中有数据作为父级:

PARENT_ID   city
----------------
20           B 
22           C
24           D

孩子:

CHILD_ID    PARENT_CHILD_JOIN        phone
------------------------------------------
2             20                     1111
3             20                     2222 
4             22                     3333

我在 child.hbm.xml 中将这两个表关联为:

<many-to-one name="myMtO" class="com.Parent" fetch="select">
        <column name="PARENT_CHILD_JOIN" not-null="true" />
</many-to-one>

在 parent.hbm.xml 中:

<set name="mySet" table="child" cascade="save-update"  inverse="true" lazy="true" fetch="select">
        <key>
            <column name="PARENT_CHILD_JOIN" not-null="true" />
        </key>
<one-to-many class="com.Child" />  
</set>

保存时我只保存parent , session.save(parent); 通过这样做,子表中的 PARENT_CHILD_JOIN 值会自动从父表的 PARENT_ID 列填充。

现在我想在这里获取数据:

select c.phone 
from child c, parent p 
where c.PARENT_CHILD_JOIN = p.PARENT_ID 

但是它说的 PARENT_CHILD_JOIN 列在子节点中不存在。这是正确的。因为在保存时我没有明确设置它。

谁能告诉我如何检索这些一对多数据?

【问题讨论】:

    标签: hibernate


    【解决方案1】:

    这是 SQL 的问题,而不是真正的休眠问题。有很多方法可以在 SQL 中修复它(例如减号语句)。 要在 Hibernate 中模拟相同的行为,您可以使用 IN/NOT IN 语句。这是我发现的最简单的方法(考虑到您必须匹配“n”个子列值,而不仅仅是一个)。

    更具体地说: 1. 从子表中选择列值 IN (...)。在 FK 列或您想要的其他列上设置投影(我将使用 FK 列,例如父母的 id)。 2. 从子表中选择列值 NOT IN (...)。在 FK 或您想要的其他列上设置投影(此处相同:我将使用 FK 列,例如父母的 id)。 3.选择所有的parrents,其中ID IN查询结果来自点1,ID NOT IN查询结果来自点2。

    这样您还可以确保不会得到父对象的重复项。如果你想要分页,你也可以使用我描述的最后一个查询。

    如果有帮助,请提供一些反馈。

    希望对你有帮助,尼古拉

    【讨论】:

    • 您有两个不同的帐户。请决定您要使用哪一个。
    【解决方案2】:

    HQL 使用实体及其属性。它不使用表名和列名。

    select c.phone from Child c inner join c.myMtO
    

    请注意,此连接(以及查询中的 where 子句)没有任何用途,因为所有子项都链接到父项(连接列不为空)。

    Hibernate 文档有一个whole chapter dedicated to HQL。阅读它。

    旁注:myMtO 真是个糟糕的名字。

    【讨论】:

    • 谢谢 JB。但是如果我想使用 where 条件,因为我想在查询中添加 where 条件 select c.phone from Child c , parent p inner join c.myMtO where p.city = 'B' ,因为它仍然返回所有结果。
    • 然后给加入的实体一个别名:select c.phone from Child c inner join c.myMtO parent where parent.city = 'B'。你读过文档吗?
    • 再次感谢 JB 的帮助!!!从文档中,我浏览了 where 子句部分并尝试了一些 foo 示例,但没有成功。但现在它返回正确的结果。谢谢!!!!
    • 你好@JB Nizet。在上述关系中,我尝试更新子表的电话列。我想将所有电话值更新为“000000”,其中父子加入条件满足(child.PARENT_CHILD_JOIN=20)。我试过了,Parent p = (Parent) session.load(Parent.class, 20);孩子 c = (孩子) p.getMySet().iterator().next(); c.setphone("00000000"); session.save(p);但它为子表中的某些记录创建重复行。我该如何更新子记录。
    • Session.save 这样做:它创建了一个新实体。您不必调用任何会话方法来修改实体。你加载它,修改它,Hibernate 会自动保存所有修改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 2018-09-08
    • 2014-05-05
    • 2011-04-07
    相关资源
    最近更新 更多