-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
EntityPreloader: add support for preloading many to many associations (…
…#4) * EntityPreloader: add support for preloading many to many associations * EntityPreloader: refactor preloadOneToMany * EntityPreloader: refactor preloading has many associations * add EntityPreloadBlogManyHasManyInversedTest
- Loading branch information
Showing
5 changed files
with
362 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace ShipMonkTests\DoctrineEntityPreloader; | ||
|
||
use Doctrine\ORM\Mapping\ClassMetadata; | ||
use ShipMonkTests\DoctrineEntityPreloader\Fixtures\Blog\Tag; | ||
use ShipMonkTests\DoctrineEntityPreloader\Lib\TestCase; | ||
|
||
class EntityPreloadBlogManyHasManyInversedTest extends TestCase | ||
{ | ||
|
||
public function testManyHasManyInversedUnoptimized(): void | ||
{ | ||
$this->createDummyBlogData(articleInEachCategoryCount: 5, tagForEachArticleCount: 5); | ||
|
||
$tags = $this->getEntityManager()->getRepository(Tag::class)->findAll(); | ||
|
||
$this->readArticleTitles($tags); | ||
|
||
self::assertAggregatedQueries([ | ||
['count' => 1, 'query' => 'SELECT * FROM tag t0'], | ||
['count' => 25, 'query' => 'SELECT * FROM article t0 INNER JOIN article_tag ON t0.id = article_tag.article_id WHERE article_tag.tag_id = ?'], | ||
]); | ||
} | ||
|
||
public function testManyHasManyInversedWithFetchJoin(): void | ||
{ | ||
$this->createDummyBlogData(articleInEachCategoryCount: 5, tagForEachArticleCount: 5); | ||
|
||
$tags = $this->getEntityManager()->createQueryBuilder() | ||
->select('tag', 'article') | ||
->from(Tag::class, 'tag') | ||
->leftJoin('tag.articles', 'article') | ||
->getQuery() | ||
->getResult(); | ||
|
||
$this->readArticleTitles($tags); | ||
|
||
self::assertAggregatedQueries([ | ||
['count' => 1, 'query' => 'SELECT * FROM tag t0_ LEFT JOIN article_tag a2_ ON t0_.id = a2_.tag_id LEFT JOIN article a1_ ON a1_.id = a2_.article_id'], | ||
]); | ||
} | ||
|
||
public function testManyHasManyInversedWithEagerFetchMode(): void | ||
{ | ||
$this->createDummyBlogData(articleInEachCategoryCount: 5, tagForEachArticleCount: 5); | ||
|
||
// for eagerly loaded Many-To-Many associations one query has to be made for each collection | ||
// https://www.doctrine-project.org/projects/doctrine-orm/en/3.2/reference/working-with-objects.html#by-eager-loading | ||
$tags = $this->getEntityManager()->createQueryBuilder() | ||
->select('tag') | ||
->from(Tag::class, 'tag') | ||
->getQuery() | ||
->setFetchMode(Tag::class, 'articles', ClassMetadata::FETCH_EAGER) | ||
->getResult(); | ||
|
||
$this->readArticleTitles($tags); | ||
|
||
self::assertAggregatedQueries([ | ||
['count' => 1, 'query' => 'SELECT * FROM tag t0_'], | ||
['count' => 25, 'query' => 'SELECT * FROM article t0 INNER JOIN article_tag ON t0.id = article_tag.article_id WHERE article_tag.tag_id = ?'], | ||
]); | ||
} | ||
|
||
public function testManyHasManyInversedWithPreload(): void | ||
{ | ||
$this->createDummyBlogData(articleInEachCategoryCount: 5, tagForEachArticleCount: 5); | ||
|
||
$tags = $this->getEntityManager()->getRepository(Tag::class)->findAll(); | ||
$this->getEntityPreloader()->preload($tags, 'articles'); | ||
|
||
$this->readArticleTitles($tags); | ||
|
||
self::assertAggregatedQueries([ | ||
['count' => 1, 'query' => 'SELECT * FROM tag t0'], | ||
['count' => 1, 'query' => 'SELECT * FROM tag t0_ INNER JOIN article_tag a2_ ON t0_.id = a2_.tag_id INNER JOIN article a1_ ON a1_.id = a2_.article_id WHERE t0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'], | ||
['count' => 1, 'query' => 'SELECT * FROM article a0_ WHERE a0_.id IN (?, ?, ?, ?, ?)'], | ||
]); | ||
} | ||
|
||
/** | ||
* @param array<Tag> $tags | ||
*/ | ||
private function readArticleTitles(array $tags): void | ||
{ | ||
foreach ($tags as $tag) { | ||
foreach ($tag->getArticles() as $article) { | ||
$article->getTitle(); | ||
} | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.