Dav*_*eto 2 doctrine query-optimization symfony doctrine-orm
我有一个名为Abono的实体,它是Check,Efectivo,Debito等其他几个实体的父类.在我的应用程序中,我使用带有这样的DQL语句的存储库类查询Abono类实例的所有对象(代码是真实类型的简化版本):
$dql = "SELECT ab FROM FranquiciaBundle:Abono AS ab";
return $em->createQuery($dql)
->getResult();
Run Code Online (Sandbox Code Playgroud)
在我的模板中,我正在显示这样的结果(再次,简化代码):
{% for abono in abonos %}
<tr>
<td>{{ abono.id }}</td>
<td>{{ abono.tipo }}</td>
</tr>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
我有5000条记录对表和探查告诉我,该应用程序是打如我所料只是一次数据库的5000倍,而不是,所以我改变阙库使用位getArrayResult()
代替getResult()
,但问题是,这句话{{ abono.tipo }}
是一个方法调用对象,而不是存储在数据库中的属性,因此它永远不会被水合到结果数组中.
所以我的问题是,如何让一个对象数组只攻击一次数据库?
UPDATE:getTipo()
类Abono 的方法返回每个对象的Late Static Binding类名,它不是关联.
public function getTipo()
{
$className = get_called_class();
$pos = strrpos($className,'\\');
return substr($className, $pos+1);
}
Run Code Online (Sandbox Code Playgroud)
好的,我找到了问题的根源.
似乎在查询与关联相反的对象时,doctrine将始终获取这些实体以创建代理实例,即使控制器或模板中不需要这些实体也是如此.因此,配置文件栏向我展示的数据库的大量点击,实际上是在学习搜索我不想要的信息的方式.
解决方案是强制在存储库中使用部分加载,如下所示:
$dql = "SELECT ab FROM FranquiciaBundle:Abono AS ab";
return $em->createQuery($dql)
->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
->getResult();
Run Code Online (Sandbox Code Playgroud)
更多信息可以在这里找到