9

我无法从教义文档中破译这段代码

/** @Entity */
class User
{
    // ...

    /**
     * @ManyToMany(targetEntity="User", mappedBy="myFriends")
     */
    private $friendsWithMe;

    /**
     * @ManyToMany(targetEntity="User", inversedBy="friendsWithMe")
     * @JoinTable(name="friends",
     *      joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@JoinColumn(name="friend_user_id", referencedColumnName="id")}
     *      )
     */
    private $myFriends;

    // ...
}

下面是我如何破译一对多的双向关系

替代文字
(来源:tumblr.com

但是如果我使用相同的方法,...下面是我得到的

替代文字 http://img514.imageshack.us/img514/2918/snagprogram0000.png

更新

我会澄清我的问题。基本上,我不明白 , 的反面是怎么myFriends回事friendsWithMe。我如何理解这段代码,更重要的是知道如何自己编写这种关系。

4

2 回答 2

12

我尝试回答我的问题,我对此仍然很模糊,希望有人能真正给出更好的答案,

所以第一个回答这个问题我是如何推导出来的$friendsWithMe

基本上,我从“解码”一个更简单、更常见、多对多的双向关系开始。

  • 1 个用户可以在多个组中
    • $用户->组
  • 1个组可以有很多用户
    • $组->用户

非常直截了当。但这在 SQL 中有何意义?

替代文字

要实现的代码

# select groups user is in
select group_id from users_groups
where user_id = 1

#select users of group
select user_id from users_groups
where group_id = 1

现在到实际模型...在 SQL

替代文字

在代码中

# select friends of given user
# $user->myFriends
select friend_id from friends
where user_id = 1;

# select users that are friends of given user
# $user->friendsWithMe
select user_id from friends
where friend_id = 1;

啊哈!选择作为给定用户朋友的用户。所以这就是我得到$friendsWithMe的。然后填补inversedBy& mappedBy& 类的其余部分?

第一次看底部注释。

替代文字

没有这么多深入的思考就不清楚了,大约 2 天。我猜

然后作为实践,我如何从头开始创建多对多自引用关系?

我将要处理的示例是...嗯,我认为这很糟糕,但是,我会尝试:) ... 1 个用户/学生可以有很多老师。1 位老师可以有多个用户/学生。1 个用户可以是这里的老师和学生。你知道在这样的论坛上,当你回答别人的问题时,你就是老师。当你问的时候,你是学生

ERD 看起来像

替代文字

一些代码选择,老师的学生,学生的老师

# select students of teacher
# $teacher->students
select student from teacher_student 
where teacher = 1;

# select teachers of student
# $student->teachers
select teacher from teacher_student
where student = 2;

好的,教义部分?

/** @Entity @Table(name="users")) */
class User {
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @Column(type="string", length="30")
     */
    private $name;
    /**
     * @ManyToMany(targetEntity="User", inversedBy="teachers")
     * @JoinTable(name="Teachers_Students",
     *              joinColumns={@JoinColumn(name="teacher", referencedColumnName="id")},
     *              inverseJoinColumns={@JoinColumn(name="student", referencedColumnName="id")}
     *              )
     */
    private $students;
    /**
     * @ManyToMany(targetEntity="User", mappedBy="students")
     */
    private $teachers;
}

它为我生成了这个表

# users
CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

#teachers_students
CREATE TABLE `teachers_students` (
  `teacher` int(11) NOT NULL,
  `student` int(11) NOT NULL,
  PRIMARY KEY (`teacher`,`student`),
  KEY `student` (`student`),
  CONSTRAINT `teachers_students_ibfk_2` FOREIGN KEY (`student`) REFERENCES `users` (`id`),
  CONSTRAINT `teachers_students_ibfk_1` FOREIGN KEY (`teacher`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

我终于做到了!让我们测试一下……嗯,我得到了

致命错误:第 61 行的 D:\ResourceLibrary\Frameworks\Doctrine\tools\sandbox\index.php 中找不到类 'Entities\User'

当我尝试做一个

$user = new User;

zz...

我也在博客上写了这个问题和我在我的tumblr上的解释

于 2010-07-21T10:32:35.087 回答
4

问题是,拥有 M:N 表:

  • 朋友用户ID
  • 用户身份

有两个用户 id 1 和 2。你只有:

朋友用户 ID = 1 和用户 ID = 2

或两者

friend_user_id = 1 和 user_id = 2 user_id = 2 和friend_user_id = 1

您可以实现这两种方式,具体取决于您如何对拥有方的集合的管理进行编码。

案例一:

public function addFriend(User $friend)
{
    $this->myFriends[] = $friend;
}

案例B:

public function addFriend(User $friend)
{
    $this->myFriends[] = $friend;
    $friend->myFriends[] = $this; // php allows to access private members of objects of the same type
}
于 2010-07-23T18:55:56.490 回答