### Install Doctrine Entity Preloader via Composer Source: https://github.com/shipmonk-rnd/doctrine-entity-preloader/blob/master/README.md This snippet shows the Composer command to add the Doctrine Entity Preloader library to your project. It's a direct dependency installation. ```sh composer require shipmonk/doctrine-entity-preloader ``` -------------------------------- ### Multi-Level Entity Preloading Example (PHP) Source: https://context7.com/shipmonk-rnd/doctrine-entity-preloader/llms.txt A comprehensive example demonstrating a real-world scenario of traversing a complex object graph, such as a blog structure, with an optimized query count. This example chains multiple `preload` calls to efficiently load categories, articles, tags, comments, and authors, resulting in a fixed number of queries regardless of data size. ```php use ShipMonk\DoctrineEntityPreloader\EntityPreloader; $entityManager = /** @var EntityManagerInterface $entityManager */; // Query 1: Fetch root categories $categories = $entityManager->getRepository(Category::class)->findAll(); $preloader = new EntityPreloader($entityManager); // Query 2: Preload all articles in these categories $articles = $preloader->preload($categories, 'articles'); // Query 3-4: Preload tags (ManyToMany = 2 queries) $tags = $preloader->preload($articles, 'tags'); // Query 5: Preload comments $comments = $preloader->preload($articles, 'comments'); // Query 6: Preload comment authors $authors = $preloader->preload($comments, 'author'); // Generate complete blog listing without additional queries foreach ($categories as $category) { echo "Category: " . $category->getName() . "\n"; foreach ($category->getArticles() as $article) { echo " Article: " . $article->getTitle() . "\n"; echo " Content: " . $article->getContent() . "\n"; echo " Tags: "; foreach ($article->getTags() as $tag) { echo $tag->getLabel() . ", "; } echo "\n"; echo " Comments:\n"; foreach ($article->getComments() as $comment) { echo " " . $comment->getAuthor()->getName() . ": "; echo $comment->getContent() . "\n"; } } } // Total: 6 queries regardless of data size // Without preloading: 1 + categories*1 + articles*2 + comments*1 queries ``` -------------------------------- ### Preload ManyToMany Associations with Doctrine Entity Preloader Source: https://context7.com/shipmonk-rnd/doctrine-entity-preloader/llms.txt This example shows how to preload ManyToMany associations, specifically 'tags' for a collection of 'articles'. It initializes the EntityPreloader, fetches articles, and then uses the preloader to fetch all associated tags efficiently. This process typically involves two queries for the preloading step (one for the join table and one for the tags themselves), in addition to the initial query for articles, resulting in a predictable query count. ```php use ShipMonk\DoctrineEntityPreloader\EntityPreloader; $entityManager = /** @var EntityManagerInterface $entityManager */; // Fetch articles (1 query) $articles = $entityManager->getRepository(Article::class)->findAll(); // Initialize preloader $preloader = new EntityPreloader($entityManager); // Preload tags for all articles (2 queries: join table query + tags fetch) $tags = $preloader->preload($articles, 'tags'); // Access tags without additional queries foreach ($articles as $article) { echo $article->getTitle() . "\n"; foreach ($article->getTags() as $tag) { echo " #" . $tag->getLabel() . "\n"; } } // Total: 3 queries (1 for articles, 1 for join table, 1 for tags) ``` -------------------------------- ### Basic Usage of EntityPreloader in PHP Source: https://github.com/shipmonk-rnd/doctrine-entity-preloader/blob/master/README.md Demonstrates how to use the EntityPreloader to preload nested associations ('articles', 'tags', 'comments') for a collection of entities. This example highlights how to avoid N+1 problems by performing preloading in batches, reducing the number of database queries. ```php use ShipMonk\DoctrineEntityPreloader\EntityPreloader; $categories = $entityManager->getRepository(Category::class)->findAll(); $preloader = new EntityPreloader($entityManager); $articles = $preloader->preload($categories, 'articles'); // 1 query to preload articles $preloader->preload($articles, 'tags'); // 2 queries to preload tags $preloader->preload($articles, 'comments'); // 1 query to preload comments // no more queries are needed now foreach ($categories as $category) { foreach ($category->getArticles() as $article) { echo $article->getTitle(), "\n"; foreach ($articles->getTags() as $tag) { echo $tag->getLabel(), "\n"; } foreach ($articles->getComments() as $comment) { echo $comment->getText(), "\n"; } } } ``` -------------------------------- ### Deep Nested Association Preloading with Doctrine Entity Preloader Source: https://context7.com/shipmonk-rnd/doctrine-entity-preloader/llms.txt This example demonstrates chaining multiple preload calls to handle deep nested associations. It shows how to preload articles for categories, then comments for those articles, and finally authors for the comments. Each preload operation is optimized to fetch data in batches, maintaining a constant and predictable number of queries regardless of the depth of the relationship traversal. ```php use ShipMonk\DoctrineEntityPreloader\EntityPreloader; $entityManager = /** @var EntityManagerInterface $entityManager */; // Fetch categories (1 query) $categories = $entityManager->getRepository(Category::class)->findAll(); $preloader = new EntityPreloader($entityManager); // Preload articles (1 query) $articles = $preloader->preload($categories, 'articles'); // Preload comments for articles (1 query) $comments = $preloader->preload($articles, 'comments'); // Preload comment authors (1 query) $authors = $preloader->preload($comments, 'author'); // Traverse all levels without additional queries foreach ($categories as $category) { foreach ($category->getArticles() as $article) { foreach ($article->getComments() as $comment) { echo $comment->getAuthor()->getName() . ": " . $comment->getContent() . "\n"; } } } // Total: 4 queries instead of 1 + n + n*m + n*m*p ``` -------------------------------- ### Configure EntityPreloader Batch Size and Fetch Join Limits in PHP Source: https://github.com/shipmonk-rnd/doctrine-entity-preloader/blob/master/README.md Illustrates how to customize the preloading process by specifying `batchSize` and `maxFetchJoinSameFieldCount` parameters. This allows fine-tuning memory usage and controlling the complexity of generated queries. ```php $preloader->preload( $articles, 'category', batchSize: 20, maxFetchJoinSameFieldCount: 5 ); ``` -------------------------------- ### Preload OneToMany Associations with Doctrine Entity Preloader Source: https://context7.com/shipmonk-rnd/doctrine-entity-preloader/llms.txt This snippet demonstrates how to use EntityPreloader to preload 'articles' (a OneToMany association) for a collection of 'categories'. It initializes the preloader with the EntityManager, fetches categories, then preloads their associated articles in a single query. Subsequent iteration over categories and their articles avoids additional database queries, reducing total queries from 1 + n to 2. ```php use ShipMonk\DoctrineEntityPreloader\EntityPreloader; use Doctrine\ORM\EntityManagerInterface; // Assume $entityManager is your Doctrine EntityManager instance $entityManager = /** @var EntityManagerInterface $entityManager */; // Fetch categories (1 query) $categories = $entityManager->getRepository(Category::class)->findAll(); // Create preloader instance $preloader = new EntityPreloader($entityManager); // Preload articles for all categories (1 additional query) $articles = $preloader->preload($categories, 'articles'); // No additional queries fired during iteration foreach ($categories as $category) { echo $category->getName() . "\n"; foreach ($category->getArticles() as $article) { echo " - " . $article->getTitle() . "\n"; } } // Total: 2 queries instead of 1 + n ``` -------------------------------- ### Control Fetch Joins for Abstract Entities (PHP) Source: https://context7.com/shipmonk-rnd/doctrine-entity-preloader/llms.txt Illustrates how to adjust the `maxFetchJoinSameFieldCount` parameter to control automatic fetch joins for inversed ToOne and abstract entity relationships. Increasing this value can reduce the number of follow-up queries for complex inheritance hierarchies at the cost of potentially more duplicate data. ```php use ShipMonk\DoctrineEntityPreloader\EntityPreloader; $entityManager = /** @var EntityManagerInterface $entityManager */; $preloader = new EntityPreloader($entityManager); $categories = $entityManager->getRepository(Category::class)->findAll(); // Increase fetch join limit to 5 (default is 1) // Higher values mean more duplicate data but fewer follow-up queries // for complex inheritance hierarchies $preloader->preload( $categories, 'articles', maxFetchJoinSameFieldCount: 5 ); foreach ($categories as $category) { foreach ($category->getArticles() as $article) { echo $article->getTitle() . "\n"; } } ``` -------------------------------- ### Preload ManyToOne Associations with Doctrine Entity Preloader Source: https://context7.com/shipmonk-rnd/doctrine-entity-preloader/llms.txt This snippet illustrates preloading ManyToOne associations, specifically the 'article' for a collection of 'comments'. By using EntityPreloader, you fetch all associated articles in a single query after fetching the comments. This prevents the common issue where accessing the parent article for each comment would result in n additional queries. ```php use ShipMonk\DoctrineEntityPreloader\EntityPreloader; $entityManager = /** @var EntityManagerInterface $entityManager */; // Fetch comments (1 query) $comments = $entityManager->getRepository(Comment::class)->findAll(); $preloader = new EntityPreloader($entityManager); // Preload articles for all comments (1 additional query) $articles = $preloader->preload($comments, 'article'); // Access parent articles without triggering individual queries foreach ($comments as $comment) { echo $comment->getContent() . "\n"; echo " Article: " . $comment->getArticle()->getTitle() . "\n"; } // Total: 2 queries instead of 1 + n ``` -------------------------------- ### Configure Batch Size for Entity Preloading (PHP) Source: https://context7.com/shipmonk-rnd/doctrine-entity-preloader/llms.txt Demonstrates how to set a custom batch size for preloading entity associations. This helps control memory usage and query complexity, especially when dealing with large collections. The default batch sizes are 1000 for ToOne and 100 for ToMany relationships. ```php use ShipMonk\DoctrineEntityPreloader\EntityPreloader; $entityManager = /** @var EntityManagerInterface $entityManager */; $preloader = new EntityPreloader($entityManager); // Fetch large collection $articles = $entityManager->getRepository(Article::class)->findAll(); // Preload with custom batch size of 20 entities per query // Default batch size is 1000 for ToOne, 100 for ToMany $preloader->preload( $articles, 'category', batchSize: 20 ); // Useful when dealing with thousands of entities to control memory foreach ($articles as $article) { echo $article->getCategory()->getName() . "\n"; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.