我在讀Doctrine docs,我遇到了這些概念並感到困惑。單向vs雙向一對一關係
我有這些表:
用戶 - > ID,角色,電子郵件,用戶名,密碼
學生 - > ID,USER_ID,FNAME,lname的
教師 - > ID,USER_ID, fname,指定
user_id是來自Users表的外鍵。那麼這應該是一種單向關係還是雙向的?
它們有什麼不同?
有人可以提供兩個現實世界的例子嗎?
主義文檔說here主義只會檢查協會的擁有方的變化。這是什麼意思?什麼樣的變化?
我在讀Doctrine docs,我遇到了這些概念並感到困惑。單向vs雙向一對一關係
我有這些表:
用戶 - > ID,角色,電子郵件,用戶名,密碼
學生 - > ID,USER_ID,FNAME,lname的
教師 - > ID,USER_ID, fname,指定
user_id是來自Users表的外鍵。那麼這應該是一種單向關係還是雙向的?
它們有什麼不同?
有人可以提供兩個現實世界的例子嗎?
主義文檔說here主義只會檢查協會的擁有方的變化。這是什麼意思?什麼樣的變化?
通常,您可以隨時使用單向或雙向關係。你設計你的代碼是因爲你會使用它。也就是說,例如,如果您聲明瞭oneToOne的單向關係,那是因爲您只需要將信息放在一邊。相反,如果您需要從兩個實體訪問關於另一個實體的信息,則需要聲明您的雙向關係。例如:
假設您的關係User-Teacher是OneToOne。案例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;
// ...
}
默認表看上去某事像:
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);
案例2:你需要訪問教師相關的用戶,但你永遠需要知道的是教師的用戶,所以你只申報老師方面的一部分。
有一些限制,主要是一對多的關係。一般來說,我會建議你使用雙向關係。
「學說文檔在這裏說,學說只會檢查協會的變化,這是什麼意思,什麼樣的變化?我不完全確定這一點,但我可以告訴你我的理解是什麼:當你在你的實體中刷新你的修改(改變他們並執行$ entityManager-> flush())之後,它只會檢查你在關係中主要實體的變化,也就是說,它不會檢查這兩個實體是否在另一個實體中改變了某種關係,而只在關係中的主要實體中進行了改變。所以你必須聲明作爲所有者一方是「基礎」一方,而不是相反。例如,在前面的例子中,如果您將您的用戶實體從您的教師實體中更改,則Doctrine不會考慮它,因爲用戶是所有者方。
例如:
$teacher->getUser()->setName('john'); //Doctrine won't check for this change
$user->getTeacher()->setStatus('dismissed'); //Doctrine will track this change
正如我告訴你,我沒有測試過那種情況下,因爲我平時聲明以及我的關係(你的FK將確定這是業主方,在這種情況下用戶) 。無論如何,進行測試並確認它並不困難。
不是這個「用戶可以是教師或學生」的場景比一般的關係更適合**繼承**的概念嗎?教師和學生仍然可以關聯,但作爲一名教師可以有很多學生。你最好從一個(可能是抽象的)用戶類繼承你的學生/老師,因爲他們共享幾乎所有的屬性(比如'name')並且僅在一些屬性上有所不同。 – nifr
我不能使用繼承,因爲我需要查詢用戶。如果我使用繼承,我只能查詢子實體。 – aBhijit
你仍然可以創建一個'AbstractUser'和一個'BaseUser',它正在從它延伸:) – nifr