【问题标题】:Need help understanding Doctrine many to many self referencing code需要帮助理解 Doctrine 多对多自引用代码
【发布时间】:2011-03-18 10:43:55
【问题描述】:

我无法从doctrine documentation破译这段代码

/** @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

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

alt text http://img514.imageshack.us/img514/2918/snagprogram0000.png

更新

我会澄清我的问题。基本上,我不明白myFriendsfriendsWithMe 的对立面是什么。我如何理解这段代码,更重要的是知道如何自己编写这种关系。

【问题讨论】:

    标签: php orm doctrine doctrine-orm


    【解决方案1】:

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

    所以第一个回答我如何使用$friendsWithMe 得出的问题

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

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

    非常直接。但这在 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
    

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

    致命错误:类 'Entities\User' 不是 在发现 D:\ResourceLibrary\Frameworks\Doctrine\tools\sandbox\index.php 第 61 行

    当我尝试做一个

    $user = new User;
    

    zzz ...

    我也在我的tumblrtumblr上写了这个问题和我的解释

    【讨论】:

    • +1 为了清楚问题并努力准备其他源材料
    • 你好。我对这种关系的教义有异议。当我将项目添加到那种集合时,刷新,然后我删除所有它们并再次刷新我收到The class 'Doctrine\ORM\Persisters\ManyToManyPersister' was not found in the chain configured namespaces。当我移除物品但至少留下一件时,一切正常。你能帮我测试一下这种行为吗?如果您在使用的学说版本发布后没有任何问题?我会很感激的。
    【解决方案2】:

    问题是,拥有 M:N 表:

    • friend_user_id
    • user_id

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

    friend_user_id = 1 和 user_id = 2

    或两者兼而有之

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

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

    案例A:

    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
    }
    

    【讨论】:

    • 关于您的新用户问题,您必须了解 PHP 5.3 命名空间的工作原理,首先您必须为“实体”命名空间设置自动加载器,然后您还必须调用“使用实体\用户” ;"能够做“新用户”而不是“新\实体\用户;”
    • 关于我的用户错误,事实证明我没有在我的班级声明顶部添加namespace Entities
    • 所以我可以说案例 1 是单向关系,而案例 2 是双向关系?我认为,如果我是社交网络的用户,every1 可以与every1 成为朋友,我不想与 some1 成为朋友,只是因为他加我为朋友?我已经测试了 M:N 关系,即使在自引用/双向设置中,当 some1 将我添加为朋友时,我也不是他的朋友。似乎更方便的是我可以找出谁是friendWithMe?
    • 是的,有点。在多对多自引用的情况下,关联和其中包含的数据都可以是单向或双向的。我同意这有点难以理解,但自我引用的东西总是如此:-)
    猜你喜欢
    • 1970-01-01
    • 2021-07-29
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-08
    • 2018-01-27
    相关资源
    最近更新 更多