2016-10-18 13 views
0

私はdoctrineクエリを持っています。doctrineを正しく使ってクエリを分割する

$object = $this->createQueryBuilder('object') 
    ->leftJoin('object.element', 'element')->addSelect('element') 
    ->leftJoin('object.element2', 'element2')->addSelect('element2') 
    ->leftJoin('object.many', 'many')->addSelect('many') 
    ->leftJoin('many.element3', 'element3')->addSelect('element3') 
    ->leftJoin('many.element4', 'element4')->addSelect('element4') 
    ->where('object.id = 1') 
    ->getQuery() 
    ->getSingleResult(); 

実際のクエリでは、より多くのジョインがあり、多くのメモリが必要になり、dbのパフォーマンスは良くありません。ネイティブSQLでは、それを分割して正しくロードします。私がやりたいことは、最初のクエリオブジェクトといくつかの基本的な結合データを読み込むことです。これは、次のようになります。

$object = $this->createQueryBuilder('object') 
    ->leftJoin('object.element', 'element')->addSelect('element') 
    ->leftJoin('object.element2', 'element2')->addSelect('element2') 
    ->where('object.id = 1') 
    ->getQuery() 
    ->getSingleResult(); 

は今、私はまたmanymany.element3many.element4をロードします。別のクエリで。 doctrine lazy loading機能を使用すると、foreachというSQLクエリが作成されますが、これは1つのクエリとしてのみ必要です。

その関係でEAGERを設定することは可能ですが、私はこのクエリのために一時的にEAGERにしたいと思っています。

答えて

0

私の問題は次のように解決しました:

私のオブジェクトは、私のコレクションに新しいセット機能を追加しました。ここ

$object = $this->createQueryBuilder('object') 
    ->leftJoin('object.element', 'element')->addSelect('element') 
    ->leftJoin('object.element2', 'element2')->addSelect('element2') 
    ->where('object.id = 1') 
    ->getQuery() 
    ->getSingleResult(); 

$object->setManies($this->getEntityManager()->getRepository(Many::class)->loadByObjectId(
     $object->getId() 
    )); 

return $object; 

多くのリポジトリ内の関数これにより

// loadByObjectId in the many repository 
$manies = $this->createQueryBuilder('many') 
    ->leftJoin('many.element3', 'element3')->addSelect('element3') 
    ->leftJoin('many.element4', 'element4')->addSelect('element4') 
    ->where('many.object = 1') 
    ->getQuery() 
    ->getResult(); 

SQLが正常に複数の要求に分割されている。このようなリポジトリに私のコードを見て

/** 
* Set manies. 
*/ 
public function setManies($manies) 
{ 
    // this clear and foreach is needed to keep it as ArrayCollection so doctrine dont need for the unitofwork request the db again 
    $this->manies->clear(); 

    foreach ($manies as $many) { 
     $this->manies->add($many); 
    } 

    return $this; 
} 

。私の場合、1回の要求で60000行ではなく、4回の要求で40行しか影響を受けませんでしたので、オブジェクトの水和をより迅速に行えます。

関連する問題