1
1

More than 1 year has passed since last update.

day19(を6日過ぎた)今日はn+1問題を避けるためにまとめてデータを取得する方法を見ていきます。

Doctrine

Entity/Author.php
<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table(name: 'authors')]
class Author
{
    #[ORM\Id]
    #[ORM\Column(type: 'integer')]
    #[ORM\GeneratedValue(strategy: 'AUTO')]
    private int $id;

    #[ORM\Column(type: 'string', length: 255)]
    private string $name;

    #[ORM\OneToMany(mappedBy: 'author', targetEntity: Book::class, fetch: 'EAGER')]
    private Collection $books;

    public function __construct()
    {
        $this->books = new ArrayCollection();
    }

    public function getId(): int
    {
        return $this->id;
    }

    public function setId(int $id): void
    {
        $this->id = $id;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): void
    {
        $this->name = $name;
    }

    public function getBooks(): Collection
    {
        return $this->books;
    }

    public function addBook(Book $book): void
    {
        if (!$this->books->contains($book)) {
            $book->setAuthor($this);
            $this->books->add($book);
        }
    }
}
<?php

declare(strict_types=1);

use App\Entity\Author;
use Doctrine\ORM\EntityManagerInterface;

require __DIR__.'/../vendor/autoload.php';

/** @var EntityManagerInterface $entityManager */
$entityManager = require __DIR__.'/bootstrap.php';

/** @var Author[] $authors */
$authors = $entityManager->getRepository(Author::class)->findAll();

foreach ($authors as $author) {
    echo $author->getName().PHP_EOL;
    foreach ($author->getBooks() as $book) {
        echo $book->getTitle().PHP_EOL;
    }
}

// 実行されたSQLのログ
// doctrine.DEBUG: Executing query: {sql} {"sql":"SELECT t0.id AS id_1, t0.name AS name_2, t3.id AS id_4, t3.title AS title_5, t3.price AS price_6, t3.description AS description_7, t3.author_id AS author_id_8 FROM authors t0 LEFT JOIN books t3 ON t3.author_id = t0.id"} []
  • Author::$booksfetch: 'EAGER' を設定すると、SQL的にはjoinした状態で取得したものをAuthorエンティティとBookエンティティとして構築してくれます。

Eloquent

<?php

declare(strict_types=1);

use App\Models\Author;

require __DIR__.'/../vendor/autoload.php';
require __DIR__.'/bootstrap.php';

$authors = Author::with('books')->get();
foreach ($authors as $author) {
    echo $author->name.PHP_EOL;
    foreach ($author->books as $book) {
        echo $book->title.PHP_EOL;
    }
}
  • modelに指定するのではなく取得時に指定します。
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1