php – 覆盖Persister:EntityRepository中的loadAll

我需要从寻呼机中的表中显示数据,同时获取子表中记录的计数.有太多的子记录要加载到内存和计数中,所以我想修改在EntityRepository中构建查询的方式.

理想情况下,我不想重新实现寻呼机功能,所以我希望在我的EntityRepository中覆盖findBy并在我的查询中添加count(),join和group by?

我怎么做到最好?我正在使用Symfony 2.8,Doctrine 2和PagerFanta

我也发现这个http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/filters.html,但它在文档上似乎很薄

最佳答案 我希望我能帮到你!

如果我理解正确,您希望从数据库中为对象的每个实例加载除了此对象的所有字段之外的子对象的数量 – 作为附加字段.对?

我不知道,如何在模型中命名父实体和子实体.但是我将从我的Web应用程序中为您的任务提供一个有效的示例.您只需重命名父实体和子实体.

有联盟计划,每个都在我的应用程序中有一组有限的帐户.所以,我有一个名为’AffiliateProgram’的父实体,我有一个名为’AffiliateProgramAccount’的子实体.

您不应该在存储库中覆盖实体类的标准方法.您只需根据需要添加方法即可.

首先,为父实体的类创建一个存储库(How to Create custom Repository Classes).我在YAML文件中进行了如下操作:

Analytics\TrafficStatisticsBundle\Entity\AffiliateProgram:

    type: entity

    table: affiliate_program

    repositoryClass: Analytics\TrafficStatisticsBundle\Entity\AffiliateProgramRepository

然后,您必须根据Doctrine描述中的路径创建父实体的存储库类.我将存储库的类与“Entity”目录中的模型类一起保存.现在,您可以根据个人需要在创建的存储库中创建自定义方法.

我建议使用Doctrine DBAL解决您的问题(How to use Doctrine DBAL).以下是我的查询示例,与您的查询完全相同:

use Doctrine\ORM\EntityRepository;

class AffiliateProgramRepository extends EntityRepository {
    /**
     * @return array
     * @throws \Doctrine\DBAL\DBALException
     */
    public function findAllAffiliatePrograms() {
//        $stmt = $this->getEntityManager()
//            ->getConnection()
//            ->prepare('
//                SELECT COUNT(apa.id) AS Number_of_accounts, ap.*
//                FROM  affiliate_program AS ap
//                LEFT JOIN affiliate_program_account AS apa ON apa.affiliate_program_id = ap.id
//                GROUP BY ap.id');
//        $stmt->execute();
//        return $stmt->fetchAll();

        $stmt = $this->getEntityManager()
            ->getConnection()
            ->prepare('
                SELECT COUNT(apa.id) AS Number_of_accounts, ap.*
                FROM  affiliate_program AS ap,
                      affiliate_program_account AS apa
                WHERE apa.affiliate_program_id = ap.id
                GROUP BY ap.id');
        $stmt->execute();
        return $stmt->fetchAll();
    }
}

请注意,对于运算符FROM,我不使用对象名称(在我的情况下为’AnalyticsTrafficStatisticsBundle:AffiliateProgram’),[LEFT |对… | INNER | OUTER] JOIN,因为它必须在DQL等中使用.相反,我使用真实的表名.
注意:不使用JOIN运算符的查询执行得更快.在我的例子中,我展示了两种方式 – 使用JOIN运算符和使用WHERE运算符相同.证明:
《php – 覆盖Persister:EntityRepository中的loadAll》

《php – 覆盖Persister:EntityRepository中的loadAll》

现在,只需调用新创建的方法,即可在控制器中根据查询获取所有对象:

<?php

namespace Testing\TestBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;

/**
 * TestController
 *
 * @Route("/test")
 */
class TestController extends Controller {
    /**
     * @Route("/", name="test_index")
     * @Method("GET")
     */
    public function indexAction() {
        $em = $this->getDoctrine()->getManager();

        $affiliatePrograms = $em->getRepository('AnalyticsTrafficStatisticsBundle:AffiliateProgram')->findAllAffiliatePrograms();
        return $this->render('TestingTestBundle:Test:test.html.twig', [
            'result' => $affiliatePrograms
        ]);
    }
}

为确保一切正常,您只需在.twig文件中编写以下代码段(例如):

{{ dump(result) }}

材料也见,见:

> How to use Raw SQL Queries in Symfony 2
> Raw SQL Queries
> Executing SQL directly in Symfony2 Doctrine

我希望你能得到的一切!

点赞