使用与Spring Data JPA集成的QueryDSL时,我遇到了一种奇怪的行为:
我在Project和Person之间有一个ManyToOne关系。如果我按所有者ID(外键)获取属于用户的所有项目,则一切都按预期工作:
QProject project = QProject.project;
QPerson owner = project.owner;
List<Project> projects = from(project).leftJoin(owner).fetch()
.where(owner.id.eq(id)).list(project);
生成的查询:
select
project0_.id as id1_1_0_,
person1_.id as id1_0_1_,
project0_.creation_date as creation2_1_0_,
project0_.name as name3_1_0_,
project0_.owner as owner4_1_0_,
person1_.name as name2_0_1_
from
project project0_
left outer join
person person1_
on project0_.owner=person1_.id
where
project0_.owner=?
但是,假设我们希望通过非外键字段(例如所有者的名字)获取属于某个人的所有项目:
QProject project = QProject.project;
QPerson owner = project.owner;
List<Project> projects = from(project).leftJoin(owner).fetch()
.where(owner.name.eq(name)).list(project);
在这些情况下,表Person不必要地连接两次(注意person1_和person2 _):
select
project0_.id as id1_1_0_,
person1_.id as id1_0_1_,
project0_.creation_date as creation2_1_0_,
project0_.name as name3_1_0_,
project0_.owner as owner4_1_0_,
person1_.name as name2_0_1_
from
project project0_
left outer join
person person1_
on project0_.owner=person1_.id cross
join
person person2_
where
project0_.owner=person2_.id
and person2_.name=?
知道为什么会这样,以及如何避免它?
答案 0 :(得分:1)
您需要创建一个别名,以确保在where部分
中重用第一个连接QProject project = QProject.project;
QPerson owner = new QPerson("owner");
List<Project> projects = from(project)
.leftJoin(project.owner, owner).fetch()
.where(owner.name.eq(name))
.list(project);