我有一个称为Abono的实体,它是Cheque,Efectivo,Debito等其他几个实体的父类。在我的应用程序中,我正在使用带有DQL语句的存储库类查询作为Abono类实例的所有对象(代码是实际的简化版本):

$dql = "SELECT ab FROM FranquiciaBundle:Abono AS ab";
return $em->createQuery($dql)
          ->getResult();


在我的模板中,我显示了这样的结果(再次是简化的代码):

{% for abono in abonos %}
    <tr>
        <td>{{ abono.id }}</td>
        <td>{{ abono.tipo }}</td>
    </tr>
{% endfor %}


我在该表上有5000条记录,分析器告诉我该应用程序的数据库访问次数是数据库的5000倍,而不是我期望的一次,因此我使用getArrayResult()而不是getResult()更改了存储库,但问题是句子{{ abono.tipo }}是对象的方法调用,而不是存储在数据库中的属性,因此它永远不会陷入结果数组中。

所以我的问题是,如何才能使一组对象仅一次访问数据库?

更新:类Abono的方法getTipo()返回每个对象的后期静态绑定类名称,它不是关联。

public function getTipo()
{
    $className = get_called_class();
    $pos = strrpos($className,'\\');
    return substr($className, $pos+1);
}

最佳答案

好的,我找到了问题的根源。

看起来,当查询作为关联的反面的对象时,即使控制器或模板中不需要这些实体,原则也会总是获取这些实体以创建代理实例。因此,配置文件栏向我显示的对数据库的巨大点击实际上是在妨碍我搜索不需要的信息的学说。

解决方案是像这样在存储库中强制使用部分负载:

$dql = "SELECT ab FROM FranquiciaBundle:Abono AS ab";
return $em->createQuery($dql)
          ->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
          ->getResult();


可以找到更多信息here

10-07 20:28