【问题标题】:JPA One To Many/Many To Many ExampleJPA 一对多/多对多示例
【发布时间】:2012-03-29 13:09:15
【问题描述】:

我正在使用:

  • 休眠
  • MySQL
  • jBoss

我必须创建一个允许用户建立友谊的应用程序。

我仍处于设计阶段,我想要这些表格:

- User {_id, name, address} 
 - Friendship {idUserA, idUserB, date}

出于我的目的,我应该与用户建立相互关系。例如 1 是 2 的朋友,间接地 2 是 1 的朋友。 所以在我的表中我认为有:

友谊 = {1, 2, ...}

我在问如何模拟这种行为。我读过他的主题:Many-to-many on the same table with additional columns 并且我已经按照这个指令从实体(休眠属性)生成数据库表。但是在这个例子中,当我加载我的朋友 A 时,我有一个包含朋友 B 的列表,而当我加载 B 时,我没有将用户 A 放入列表中。

我该如何实现这种该死的相互关系?

【问题讨论】:

标签: java mysql sql hibernate jpa


【解决方案1】:

据我了解,这个样本的相互关系并不是隐含的。要从 A->B 和 B->A 建立友谊关系,您必须在表中添加两个条目,或者您必须实现两个集合并返回两个列表的交集:

@OneToMany(mappedBy="myFriends")
private List<MyFriends> myFriends;

@OneToMany(mappedBy="me")
private List<MyFriends> iAmFriendOf;

...

Set<MyFriends> getFriends() {
    Set<MyFriends> friends = new HashSet<MyFriends>();
    friends.addAll(myFriends);
    friends.addAll(iAmFriendOf);
    return friends;
}

【讨论】:

    【解决方案2】:

    实际上,我不是 OneToMany 尤其是 ManyToMany 关系的忠实粉丝。我更喜欢像你一样有另一张像友谊这样的桌子。据我了解,您正在混合使用方法。对我来说,最简单的方法是有一张友谊表,你需要在这张表中匹配两个朋友,所以设计可以是:

    @Entity
    public class User{
    
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private int id;
    
        @Column
        private String name;
    
        @Column
        private String address;
    
    }
    
    @Entity
    public class Friendship {
    
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private int id;
    
        @ManyToOne 
        @JoinColumn(name="friend_requester_id")
        private User friendRequester;
    
        @ManyToOne 
        @JoinColumn(name="friend_accepter_id")
        private User friendAccepter;
    
        private Date date;
    
    }
    

    列出朋友时,您可以列出朋友(因为他们是另一张桌子)或使用这张桌子的朋友。但是,如果您只想列出朋友但不那么难,那就有点棘手了。您可以使用getFriends(List&lt;Friendship&gt; friendships, int userId) 方法并列出以下朋友:

      List<User> friends ...
    
      Iterator iterator = friendships.iterator();
      while (iterator.hasNext()) {
         Friendship friendship = (Friendship) iterator.next();
         if (friendship.getFriendRequester().getId != userId) {
             friends.add(friendship.getFriendRequester);
         } else {
             friends.add(friendship.getFriendAccepter);
         }
      }
    
      return friends;
    

    此实现的另一个优点是,您可以区分谁稍后请求成为朋友(如果需要)。

    在我看来,是的,它似乎很复杂且工作量过大,但它相当易于维护且不那么痛苦。

    【讨论】:

    • 一个人可以有多个友谊——这是一对多的关系。通过中间表如何改变这种情况?它仍然是 1-Many ......我也很好奇你如何存储(比如说)地址 - 多个 ppl 可以住在同一个地址,一个人可以有多个地址 - 不使用 Many-Many 关系?除非我误解了你的开头段落?
    • 是的,当然..例如,如果用户有另一个朋友,则意味着友谊表中的新记录..所以每个友谊在友谊表中都有记录。您可以在不使用多对多关系的情况下实现多个地址多人。实际上,在大多数应用程序中,只需要一个地址作为当前地址。因此,您在用户表中的用户和地址表是多对一关系的地址,因此您在同一个地址中有多个用户。但是,如果您需要多个地址中的多个用户,则需要一个具有 user_id、address_id 的 useraddress 表,因此现在您可以拥有所需的内容。
    • 同意,地址不是一个很好的例子,通常它是一个 1-Many,但你用包含 user_idaddress_id 的表格描述的内容据我了解(根据Wikipedia),这是一种多对多关系。
    • 是的,这确实是多对多的关系,因为从逻辑上讲,我们正在做多对多的映射。然而,实现有点不同,因为同一张表中的多对多关系存在一些问题。我找到了一个很好的页面,它可以比我解释得更好;)我希望这更清楚:ManyToMany#Advanced
    猜你喜欢
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    • 2017-08-19
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多