我试图了解Doctrine 2 ORM关系,我认为我已经掌握了它,但在阅读了一些symfony食谱条目后,我怀疑我实际上有点困惑。
我目前有一个系统,其中模板可以包含多个模块(包括每种类型的多个模块),并且多个模板可以使用相同的模块。
我认为这将保证ManyToMany的关系,并且确实在看我的桌子,它似乎工作得很好。
但是我意识到,当我编写数据库查询时,我需要按特定顺序加载模块,这意味着我的连接表需要有第三个'order_by'列。我已经读过真正的连接表只有两列。
因此混乱。我应该如何在我的实体中设置它?
答案 0 :(得分:4)
就像@Kris所说的那样 - 你会选择一对多的中间实体。如果您选择“多对多”,那么您将不会拥有中间表的类文件,这在大多数情况下都是一个问题。
M-N假设:一个学生在多个课程学习,一个课程可以有很多学生。
以下两个示例都为您提供了数据库中的ERD,但您希望获得一个到多个版本。
MANY to MANY:
这将在数据库中创建StudentCourse
实体,但是您没有看到实际的类文件供您处理。
class Student
{
protected $id;
protected $name;
/**
* @ORM\ManyToMany(targetEntity="Course")
* @ORM\JoinTable(
* name="StudentCourse",
* joinColumns={@ORM\JoinColumn(name="studentId", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="courseId", referencedColumnName="id")}
* )
*/
private $course;
}
class Course
{
protected $id;
protected $name;
}
ONE TO MANY:
这将在数据库中创建StudentCourse
实体,如您所见,有一个实际的类文件供您在编码时处理,例如persist()等。
class Student
{
protected $id;
protected $name;
/**
* @ORM\OneToMany(targetEntity="StudentCourse", mappedBy="studentMap",
* cascade={"persist", "remove"})
*/
protected $studentInverse;
}
class StudentCourse
{
protected $id;
/**
* @ORM\ManyToOne(targetEntity="Course", inversedBy="courseInverse")
* @ORM\JoinColumn(name="course", referencedColumnName="id",
* nullable=false, onDelete="CASCADE")
*/
protected $courseMap;
/**
* @ORM\ManyToOne(targetEntity="Student", inversedBy="studentInverse")
* @ORM\JoinColumn(name="student", referencedColumnName="id",
* nullable=false, onDelete="CASCADE")
*/
protected $studentMap;
}
class Course
{
protected $id;
protected $name;
/**
* @ORM\OneToMany(targetEntity="StudentCourse", mappedBy="courseMap",
* cascade={"persist", "remove"})
*/
protected $courseInverse;
}
修改强>
onDelete="CASCADE"
和cascade={"persist", "remove"}
位不是强制性的。它们处理数据冗余。 Is it bad to use redundant relationships?
答案 1 :(得分:1)
你需要一个OneToMany / ManyToOne 如果您不需要保存订单,那将是一个很多人,但是既然如此,那么中间表现在必须是它自己的实体。 所以你需要以下实体
模板
使用OneToMany
TemplateModules(可能是这个名称的更好名称)
使用ManyToOne
模块