2016-11-29 3 views
4

私は、ページャのテーブルからデータを表示すると同時に、子テーブルのレコード数を取得する必要があります。メモリにロードしてカウントする子レコードが多すぎますので、EntityRepositoryでクエリがどのように構築されるかを変更したいと思います。オーバーライドPersister:EntityRepositoryのloadAll

理想的には、ページャ機能を再実装したくないので、EntityRepositoryでfindByをオーバーライドして、count()、join、group byをクエリに追加しようとしていますか?

どうすればよいですか?私はまた、このhttp://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/filters.htmlが見つかりましたが、それはドキュメント

私はあなたを助けることを願って
+1

あなたの質問は私には不明です。ページャはあなたの問題にどのように関連していますか? [カスタムDQLクエリ](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html)で問題を解決できませんか? –

+0

はい私はカスタムSQLクエリが必要だと私は理解していますが、私はそれを接続するために私のリポジトリに関数を見つけることができません。 findByをオーバーライドすると、ページングパラメータを渡す方法を教えてください。 – jdog

+0

$ this-> getEntityManager() - > createQuery($ dql); '。 '$ dql'はDQL文字列です。 –

答えて

1

に薄いと思われるのSymfony 2.8、教義2及びPagerFanta

を使用しています!

私が正しく理解していれば、オブジェクトのインスタンスごとにデータベースから、このオブジェクトのすべてのフィールドに加えて子オブジェクトの数を追加フィールドとして追加する必要があります。右?

親エンティティと子エンティティがモデルでどのように名前付けされているかわかりません。しかし、私はあなたの仕事のための実例をWebアプリケーションから提供します。親子エンティティの名前を変更するだけです。

アフィリエイトプログラムがあり、それぞれが自分のアプリケーションに有限のアカウントを持っています。だから、私は 'AffiliateProgram'という親エンティティを持っていて、私は 'AffiliateProgramAccount'という子エンティティを持っています。

エンティティのクラスについては、リポジトリの標準メソッドをオーバーライドしないでください。必要に応じてメソッドを追加するだけです。

まず、親エンティティのクラス用のリポジトリを作成してください(How to Create custom Repository Classes)。次のように私は説明してYAMLファイルでそれを行う:

Analytics\TrafficStatisticsBundle\Entity\AffiliateProgram: 

    type: entity 

    table: affiliate_program 

    repositoryClass: Analytics\TrafficStatisticsBundle\Entity\AffiliateProgramRepository 

次に、あなたが教義の説明では、パスに応じて、あなたの親エンティティのリポジトリクラスを作成する必要があります。私はリポジトリのクラスを '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(); 
    } 
} 

私はオブジェクト名を使用していないことに注意してください:[左からオペレータのために(私の場合は「AnalyticsTrafficStatisticsBundle AffiliateProgramを」)|右|インナー| OUTER] DQLなどで使用する必要があるため、JOINを使用します。代わりに、実際のテーブル名を使用します。 注:JOIN演算子を使用しないクエリは、より高速に実行されます。私の例では、2つの方法を示しました.JOIN演算子とWHERE演算子を使用して同じものを使用しました。証明: Using WHERE operatorUsing JOIN operator

今、あなたが得ることができるコントローラでクエリに応じて、単純に新たに作成されたメソッドを呼び出すことにより、すべてのオブジェクト:

<?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 
     ]); 
    } 
} 

、すべてが動作することを確認するためには、次のスニペットを書くだけです。(例えば)小枝ファイル:

{{ dump(result) }} 

材料も、ここを参照してください:

  1. How to use Raw SQL Queries in Symfony 2
  2. Raw SQL Queries
  3. Executing SQL directly in Symfony2 Doctrine

を、私はそれはあなたが必要とするすべてですね!

関連する問題