我正在尝试使用Doctrine优化symfony应用程序。我偶然发现了以下问题:
在视图中我使用了$ project-> getProgress();但是通过这样做,查询的数量会随着项目的增加而增加。所以我尝试使用左连接将进度放入项目查询(覆盖findAll方法),但这没有用。查询数量实际上增加了。
public function findAll($hydrationMode = null)
{
$q = $this->createQuery('p')
->leftJoin('p.progress pr')
->leftJoin('pr.sfGuardUser u')
->leftJoin('p.raws r')
->leftJoin('p.series');
return $q->execute(array(), $hydrationMode);
}
这是我尝试使用尽可能少的查询创建的结果:
array() {
[0]=>
array() {
["id"]=> string(1) "1"
...
["progress"]=>
array() {
array() {
array() { progress1 }
array() { progress2 }
array() { progress3 }
....
}
}
}
我查看了symfony和Doctrine的文档,但找不到我的答案。我也在谷歌搜索了很长一段时间。 (我一直在寻找解决方案已经有几个月了)我希望我已经足够好地描述了我的问题。
的schema.yml:
projects:
actAs:
Timestampable: ~
columns:
user_id: integer(4)
series_id: bigint
pages: int
chapter: string
translators_id: bigint
proofreaders_id: bigint
cleaners_id: bigint
typesetters_id: bigint
raws_id: bigint
hide_project: bool
complete: bool
relations:
sfGuardUser:
local: user_id
foreign: id
onDelete: CASCADE
series:
local: series_id
foreign: id
type: one
foreignType: many
onDelete: CASCADE
progress:
local: id
foreign: projects_id
onDelete: CASCADE
type: one
foreignType: many
projectsProgress:
actAs: [Timestampable]
columns:
projects_id: bigint
user_id: integer(4)
job:
type: enum
notnull: true
values: [tl,pr,cl,ts]
beginpage: int
endpage: int
complete: bool
file: string
url: clob
relations:
sfGuardUser:
local: user_id
foreign: id
onDelete: CASCADE
projects:
local: projects_id
foreign: id
onDelete: CASCADE
foreignAlias: progress
答案 0 :(得分:0)
您需要修改提取Project
对象以包含联接的查询。通常,获取Project
个对象的查询应放在ProjectTable
。
如果您要修改Project
的所有查询或查询子集,请查看Doctrine Query Execution Listeners。
答案 1 :(得分:0)
使用水合物模式的问题是您可以获取不使用的数据。我真的不知道doctrine如何获取所有数据,但是假设每个项目都会带来所有必需的数据,至少会增加一个查询......
对于复杂查询(和优化),我更喜欢进行手动查询,并设法将所有需要的数据放在一个查询中,例如:
$query = "SELECT ... FROM projects p LEFT JOIN progress pr (LEFT JOIN sfGuardUser u (LEFT JOIN...) ON pr.user_id = u.id ) ON p.id = pr.projects_id"
$rs = Doctrine_Manager::getInstance()->getCurrentConnection()->fetchAssoc($query);
$ rs 包含所选数据的数组。拥有所有数据,您可以根据需要创建数组,但请记住,这样您可以执行一个查询(减少数据库负载),但添加一些时间机器解析数组。