2

我有一个名为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 %}

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

所以我的问题是,我怎样才能让一组对象只访问数据库一次?

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

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

3 回答 3

6

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

似乎在查询作为关联反面的对象时,学说总是会获取这些实体以创建代理实例,即使控制器或模板中不需要这些实体。因此,个人资料栏向我显示的大量数据库点击量实际上是一种教条,阻碍了我搜索我不想要的信息。

解决方案是强制在存储库中使用部分加载,如下所示:

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

更多信息可以在这里找到

于 2013-01-06T18:10:41.673 回答
2

您可以使用 fetch join 来获取相关信息,并将其与第一个查询一起合并。

“从 FranquiciaBundle 中选择 ab,tipo:Abono AS ab JOIN ab.tipo”

另见: http ://doctrine-orm.readthedocs.org/en/2.0.x/reference/dql-doctrine-query-language.html#joins

于 2013-01-03T15:03:59.173 回答
1

Erik 是对的,但是您不必通过 sql 进行优化,doSelectJoinAll 就可以解决问题。

于 2013-01-03T15:33:23.867 回答