我有一个与单个(!)联接表与多个其他表相关的表。
这是一个粗略的草图:
pupils_table (master table)
---
id name
&害羞;
teachers_table (related table 1)
---
id first_name last_name ...
&害羞;
courses_table (related table 2)
---
id start_date end_date ...
&害羞;
join_table (relates master to both (!) related tables)
---
id master_id teacher_id course_id
与他们的老师和课程获得完整学生记录的标准SQL查询是:
select p.*, t.*, c.* from pupils_table p
left join join_table jt on jt.master_id = p.id
inner join teachers_table t on t.id = jt.teacher_id
inner join courses_table c on c.id = jt.courses_id
;
但是,我很难使用学说的关系映射和查询布构建器来创建这样的查询。我发现的所有示例都使用将主表与仅一个相关表相关的加入表。
如果我的主人:
,这是我在实体中尝试的。/**
* @ORMTable(name="pupils_table")
*/
class Pupils
{
/**
* @ORMColumn(type="integer")
* @ORMId()
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORMManyToMany(targetEntity="AppBundleEntityTeachers")
* @ORMJoinTable(name="join_table",
* joinColumns={@ORMJoinColumn(name="master_id", referencedColumnName="id")},
* inverseJoinColumns={@ORMJoinColumn(name="teacher_id", referencedColumnName="id")} * )
*/
private $teachers;
/**
* @ORMManyToMany(targetEntity="AppBundleEntityCourses")
* @ORMJoinTable(name="join_table",
* joinColumns={@ORMJoinColumn(name="master_id", referencedColumnName="id")},
* inverseJoinColumns={@ORMJoinColumn(name="course_id", referencedColumnName="id")} * )
*/
private $courses;
...
到目前为止,我还没有在老师和课程实体中引入任何特殊关系。
我的查询构建看起来像这样:
$qb->select('p', 't', 'c')
->from('AppBundle:Pupils', 'p')
->innerJoin('p.teachers', 't')
->innerJoin('p.courses', 'c')
;
$res = $qb->getQuery()->getResult();
结果是一个Weired SQL查询,具有错误的内部联接序列,结果无法正确嵌套相关数据(可以使用此SQL预期):
SELECT ... FROM pupils_table c0_
INNER JOIN join_table c3_ ON c0_.id = c3_.master_id
INNER JOIN teachers_table c1_ ON c1_.id = c3_.teacher_id
INNER JOIN join_table c4_ ON c0_.id = c4_.master_id
INNER JOIN courses_table c2_ ON c2_.id = c4_.course_id
如您所见,内部连接之前没有左连接,并且连接了两次。我知道我没有在我的QueryBuilder命令中明确添加左JOIN,但是如果仅在DocBlock注释中提到加入表并且没有自己的实体(这是文档告诉我的),我该怎么办。
要实现这种类型的映射,我将使用该交界实体,该实体将保存对这三个实体的参考,该结构将生成您在帖子中提到的正确的SQL。以下是我们如何创建和关联交界实体的解释
首先不要直接链接这三个实体,而是将您的交界器实体与以下方式链接到这三个实体
PupilTeacherCourseHasMany ---ManyToOne---> Pupils
PupilTeacherCourseHasMany ---ManyToOne---> Teachers
PupilTeacherCourseHasMany ---ManyToOne---> Courses
Pupils ---OneToMany---> PupilTeacherCourseHasMany
Teachers ---OneToMany---> PupilTeacherCourseHasMany
Courses---OneToMany---> PupilTeacherCourseHasMany
学生类
/**
* Pupils
* @ORMTable(name="pupils")
* @ORMEntity
*/
class Pupils
{
/**
* @ORMOneToMany(targetEntity="NameSpaceYourBundleEntityPupilTeacherCourseHasMany", mappedBy="pupils",cascade={"your options"} )
*/
protected $pupilTeacherCourseHasMany;
}
教师类
/**
* Teachers
* @ORMTable(name="teachers")
* @ORMEntity
*/
class Teachers
{
/**
* @ORMOneToMany(targetEntity="NameSpaceYourBundleEntityPupilTeacherCourseHasMany", mappedBy="teachers",cascade={"your options"} )
*/
protected $pupilTeacherCourseHasMany;
}
课程类
/**
* Courses
* @ORMTable(name="courses")
* @ORMEntity
*/
class Courses
{
/**
* @ORMOneToMany(targetEntity="NameSpaceYourBundleEntityPupilTeacherCourseHasMany", mappedBy="courses",cascade={"your options"} )
*/
protected $pupilTeacherCourseHasMany;
}
pupilteachercoursehasmany
/**
* PupilTeacherCourseHasMany
* @ORMTable(name="pupilteachercoursehasmany")
* @ORMEntity
*/
class PupilTeacherCourseHasMany
{
/**
* @ORMManyToOne(targetEntity="NameSpaceYourBundleEntityPupils", cascade={"your options"})
* @ORMJoinColumn(name="pupil_id", referencedColumnName="id")
*/
protected $pupils;
/**
* @ORMManyToOne(targetEntity="NameSpaceYourBundleEntityTeachers", cascade={"your options"})
* @ORMJoinColumn(name="teacher_id", referencedColumnName="id")
*/
protected $teachers;
/**
* @ORMManyToOne(targetEntity="NameSpaceYourBundleEntityCourses", cascade={"your options"})
* @ORMJoinColumn(name="course_id", referencedColumnName="id")
*/
protected $courses;
}
现在要获取所有详细信息,您的学说查询将是
之类的东西$qb->select('p', 't', 'c')
->from('AppBundle:Pupils', 'p')
->leftJoin('AppBundle:PupilTeacherCourseHasMany ptc')
->innerJoin('ptc.teachers', 't')
->innerJoin('ptc.courses', 'c')
;
$res = $qb->getQuery()->getResult();
有关参考,请参阅我的另一个答案