1

阅读有关 Hibernate 的 wiki 页面,我阐述了一些令人困惑的结论:

1) Bidirectionality is reccomended in one-to-many

2) Bidirectionality is optional in many-to-one

3) Bidirectionality is normally present in many-to-many

4) Unidirectionality is reccomended in one-to-one relationships, 
using as owner class the one with the primary key of the 
relation (not the foreign key).

这些说法是真的吗?您是否有任何示例来解释为什么在某些情况下建议使用单向性而在其他情况下建议使用双向性?

这是维基页面(在“概念”下阅读):

http://wiki.elvanor.net/index.php/Hibernate

4

1 回答 1

1

请注意,Hibernate 上下文中的“双向性”意味着在您的 Java 类中,关系的双方都保持到另一方的链接。它对底层数据库模式没有影响(除了索引集合的情况,见下文),只是您是否希望 Java 端反映这一点。

对于您的所有结论,“推荐”实际上转化为“考虑到您的业务逻辑,它通常最终是有意义的,您会这样做”。

您真的很想通读Hibernate Core Reference Manual的第 7 章和第 8 章。

  1. 如果您需要,建议使用它。指定双向关系带来了很多便利。特别是可以在业务逻辑的两端导航关系。但是,如果您实际上不需要这样做,则没有任何好处。使用最适合这种情况的任何东西。在实践中,我发现我想更频繁地指定与 Hibernate 的关系的两端——但这不是规则,而是反映了我想要完成的任务。

  2. 这是真实的。在多对一(或一对多)关系中,它是可选的。考虑以下架构:

    table: users
    fields: userId, userName
    
    table: forumPosts
    fields: postId, userId, content
    


    forumPosts.userId外键 在哪里users。您的 DAO 类可能是(为简洁起见,省略了 getter/setter):

    public class User {
        private long userId;
        private String userName; 
    }
    
    public class ForumPost {
        private long postId;
        private User user; 
        private String content;
    }
    


    如您所见,这是一个单向的多对一关系(ForumPost-to- User)。ForumPost指向用户的链接,但User不包含ForumPosts.

    然后,您可以添加一对多映射以User使其具有ForumPosts. 如果您使用像集合这样的非索引集合,这对数据库架构没有影响。仅仅通过指定 Hibernate 的双方,您就可以实现双向(使用与上面完全相同的模式),例如:

    public class User {
        private long userId;
        private String userName; 
        private Set<ForumPost> forumPosts;
    }
    
    public class ForumPost {
        private long postId;
        private User user; 
        private String content;
    }
    


    Hibernate 现在将在必要时填充 User.forumPosts(主要是SELECT * FROM forumPosts WHERE userId = ?)。这里双向和单向之间的唯一区别是,在一种情况下,Hibernate 填充了一组ForumPostsin User,而在另一种情况下则没有。如果您必须获取任何给定用户帖子的集合,您将希望使用这样的双向关系,而不是显式构建 HQL 查询。根据您关系中的反向/插入/更新/级联选项,您还可以通过修改用户的帖子集来添加和删除帖子,这可能更准确地反映了您的业务逻辑(或不是!)。

    我指定非索引的原因集合不会影响底层架构,因为如果您想使用像列表这样的有序索引集合,您必须在 forumPosts 表中添加一个额外的列表索引字段(尽管您不必将其添加到 ForumPost DAO 类)。

  3. 这是真的,但不是必需的,而且比这更深。和上面一样。双向性通常以多对多的形式存在。多对多关系是通过第三个连接表实现的。您在关系的两端指定此表的详细信息。您可以简单地指定一侧的关系,现在它是单向关系。同样,您是否告诉Hibernate 映射决定了它是单向的还是双向的(在 Hibernate 的上下文中)。在这种情况下,除非您使用有序索引集合,否则它对基础架构也没有影响。事实上, Hibernate 参考手册中的多对多示例是单向设置。

    实际上,拥有单向多对多关系会很奇怪,除非您正在使用现有的数据库模式并且您的特定应用程序的业务逻辑不需要关系的任一方。但是,通常,当您决定需要多对多关系时,您已经决定这样做是因为您需要维护关系双方的引用集合,并且您的 DAO 类将反映这种需求。

    所以这里正确的结论不是仅仅是“双向性通常存在于多对多中”,而是“如果您设计了一个带有连接表的数据库,但您的业务逻辑只使用单向关系,您应该质疑您的模式是否合适为您的应用程序(很可能是)”。

  4. 这不是真的。与上述所有要点完全相同。如果您需要从双方导航一对一的关系,那么您希望使其成为双向的(指定映射的双方到 Hibernate)。如果不是,则将其设为单向(不要将映射的两侧都指定为 Hibernate)。这又归结为在您的业务层中有意义的事情。

我希望这会有所帮助。我留下了很多错综复杂的东西。你真的应该通读 Hibernate 文档——它的组织不是特别好,但是第 7 章和第 8 章会告诉你关于集合映射你需要知道的一切。

当我从头开始设计应用程序和数据库时,就个人而言,我试图完全忘记 Hibernate 和数据库。我以一种对我的业务需求有意义的方式设置我的 DAO,设计一个与之匹配的数据库模式,然后设置 Hibernate 映射,然后对模式进行任何最终调整(例如,为有序集合添加索引字段),如果必要的。

于 2013-08-12T15:30:31.817 回答