简体   繁体   English

单向与双向的一对一关系

[英]unidirectional vs bidirectional in one-to-one relationship

I was reading Doctrine docs and I came across these concepts and got confused. 我正在阅读Doctrine文档 ,我遇到了这些概念而感到困惑。

I have these tables: 我有这些表:

Users -> id, role, email, username, password 用户 - > id,角色,电子邮件,用户名,密码

Students -> id, user_id, fname, lname 学生 - > id,user_id,fname,lname

Teachers -> id, user_id, fname, designation 教师 - > id,user_id,fname,指定

user_id is the foreign key from Users table. user_id是Users表中的外键。 So is this supposed to be a unidirectional relation or bidirectional? 这应该是单向关系还是双向关系?

How do they differ? 他们有什么不同?

Can someone please provide real world examples for both? 有人可以为两者提供真实世界的例子吗?

Doctrine docs says here that Doctrine will only check the owning side of an association for changes. Doctrine docs 在这里说, Doctrine只会检查协会的拥有方是否有变化。 What does that mean? 这意味着什么? What kind of changes? 什么样的变化?

In general, you can use both unidirectional or bidirectional relationships whenever you want. 通常,您可以随时使用单向或双向关系。 You design your code due to the use you will do of it. 您可以根据自己的需要设计代码。 That is, for example, if you are declaring an unidirectional relationship oneToOne is because you only need to have the information in one side. 也就是说,例如,如果要声明单向关系,oneToOne是因为您只需要在一侧获取信息。 At the contrary side, if you need to access from both entities the information about the other entity, you need to declare your bidirectional relationship. 相反,如果您需要从两个实体访问有关另一个实体的信息,您需要声明您的双向关系。 For example: 例如:

Supposing that your relationship User-Teacher is OneToOne. 假设您的用户 - 教师关系是OneToOne。

Case 1: You'll want to know if a user is a teacher and also you'll need to know which user is related to a Teacher entity => you use bidirectional relationship. 案例1:您需要知道用户是否是教师,并且您还需要知道哪个用户与教师实体相关=>您使用双向关系。

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

    /**
     * @OneToOne(targetEntity="Teacher", mappedBy="user")
     */
    private $teacher;

    // ...
}

/** @Entity */
class Teacher
{
    // ...

    /**
     * @OneToOne(targetEntity="User", inversedBy="teacher")
     * @JoinColumn(name="user_id", referencedColumnName="id")
     */
    private $user;

    // ...
}

Default tables would look sth like: 默认表看起来像:

CREATE TABLE Teacher (
    id INT AUTO_INCREMENT NOT NULL,
    user_id INT DEFAULT NULL,
    PRIMARY KEY(id)
) ENGINE = InnoDB;
CREATE TABLE User (
    id INT AUTO_INCREMENT NOT NULL,
    PRIMARY KEY(id)
) ENGINE = InnoDB;
ALTER TABLE Teacher ADD FOREIGN KEY (user_id) REFERENCES User(id);

Case 2: You need to access the teachers related user but you'll never need to know the users that are teachers, so you declare only the part of the teacher side. 案例2:您需要访问教师相关用户,但您永远不需要知道作为教师的用户,因此您只声明教师方面的部分。

Reference: http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html#one-to-one-unidirectional 参考: http//docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html#one-to-one-unidirectional

There are a few restrictions, mainly in oneToMany relationships. 有一些限制,主要是在oneToMany关系中。 In general, I'll advice you to use bi-directional relationships. 一般来说,我会建议你使用双向关系。

"Doctrine docs says here that Doctrine will only check the owning side of an association for changes. What does that mean? What kind of changes?" “Doctrine docs在这里说,Doctrine只会检查一个协会的拥有方面是否有变化。这意味着什么?有什么样的变化?”

I'm not totally sure of this, but I can tell you what I understand of that: when you are flushing your changes in your entities (after changing sth on them and executing $entityManager->flush()), it will only check your changes from the main entity in the relationship, that is, it won't check in both entities if you have changed sth in the other one, only in the main one in the relationship. 我并不完全确定这一点,但我可以告诉你我对此的理解:当你在实体中刷新你的更改时(在更改它们并执行$ entityManager-> flush()之后),它只会检查您对关系中主实体的更改,也就是说,如果您在另一个实体中更改了某个实体,则不会检查这两个实体,只会在关系中的主实体中更改。 So you must declare as the owner side that one that is the "base" one, and not at the contrary. 因此,您必须声明所有者是“基础”的,而不是相反。 For example, in the previous example, if you changed your user entity from your teacher entity, Doctrine won't take it in account because User is the owner side. 例如,在上一个示例中,如果您从教师实体更改了用户实体,则Doctrine不会将其记入帐户,因为User是所有者方。

ex: 例如:

$teacher->getUser()->setName('john'); //Doctrine won't check for this change
$user->getTeacher()->setStatus('dismissed'); //Doctrine will track this change

As I tell you, I've not tested that kind of cases because I usually declare well my relationships (your FK will define which is the owner side, in this case User). 正如我告诉你的那样,我没有测试过这种情况,因为我通常会很好地宣布我的关系(你的FK将定义哪个是所有者方,在这种情况下是User)。 It won't be difficult to make a test and confirm it, anyhow. 无论如何,进行测试并确认它并不困难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM