Upgrade to Pro — share decks privately, control downloads, hide ads and more …

30分でDoctrineの仕組みと使い方を完全にマスターする / phpconkagawa 2...

30分でDoctrineの仕組みと使い方を完全にマスターする / phpconkagawa 2025 Doctrine

Avatar for Takashi Kanemoto

Takashi Kanemoto

November 24, 2025
Tweet

More Decks by Takashi Kanemoto

Other Decks in Programming

Transcript

  1. / 147 30 Doctrine 方 2 025 / 11 /

    2 4 PHP 香 2025 @ttskch  1 # #phpconkagawa
  2. / 147 Symfony 用 PHP ORM Doctrine OSS Doctrine DBAL

    Doctrine ORM Doctrine ⾒ Doctrine ORM Doctrine  12
  3. / 147 Database Abstraction Layer DB DB DB DB DBAL

    DB DB 一 Doctrine DBAL  14
  4. / 147 Object-Relational Mapper OOP 言 RDB DB PHP ORM

    Eloquent ORM Laravel ORM Doctrine ORM  15
  5. / 147 ORM 2 Eloquent Active Record Doctrine Data Mapper

    PoEAA Eloquent 比  17 https://www.martinfowler.com/eaaCatalog/activeRecord.html https://www.martinfowler.com/eaaCatalog/dataMapper.html
  6. / 147 Active Record vs Data Mapper  22 Active

    Record Data Mapper 手 長 高 比 高
  7. / 147 Doctrine DDD DDD ⾒ DB 一 1 PoEAA

    Identity Map  28 https://martinfowler.com/eaaCatalog/identityMap.html
  8. / 147 // Eloquent dump(spl_object_hash( Article::find(1), )); dump(spl_object_hash( Article::find(1), ));

    dump(spl_object_hash( Article::find(1), )); // Doctrine dump(spl_object_hash( $articleRepository->find(1), )); dump(spl_object_hash( $articleRepository->find(1), )); dump(spl_object_hash( $articleRepository->find(1), ));  29 // "000000000000085b0000000000000000" // "000000000000085b0000000000000000" // "000000000000085b0000000000000000" // "00000000000012250000000000000000" // "00000000000011f90000000000000000" // "00000000000011f70000000000000000"
  9. / 147  32 #[ORM\Entity] #[ORM\Table(name: 'article')] class Article {

    #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; }
  10. / 147  33 #[ORM\Entity] #[ORM\Table(name: 'article')] class Article {

    #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; } POPO Plain Old PHP Object DB
  11. / 147 Doctrine DB 一 PoEAA Unit of Work Unit

    of Work  51 https://www.martinfowler.com/eaaCatalog/unitOfWork.html
  12. / 147 DB  71 Unit of Work DB Doctrine

    Unit of Work 自身 DB 行
  13. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; }
  14. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; } Article article
  15. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; } ORM Doctrine
  16. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; } $id ID Doctrine 自 id integer
  17. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; } $title title string 大長 255 文
  18. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; } $content content text NULL
  19. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; }
  20. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; } 方
  21. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; }
  22. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; }
  23. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; } string integer text
  24. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; } string integer text 身 文
  25. / 147 integer string text Doctrine DBAL DB  93

    DBAL MySQL PostgreSQL SQLite integer INT UNSIGNED INT INTEGER string VARCHAR VARCHAR VARCHAR text TEXT TEXT VARCHAR(MAX) https://www.doctrine-project.org/projects/doctrine-dbal/en/ 4 . 3 /reference/types.html#mapping-matrix
  26. / 147 // ΤϯςΟςΟϚωʔδϟʔ͔Β // ArticleΤϯςΟςΟ༻ͷϦϙδτϦΛऔಘ $articleRepository = $entityManager->getRepository(Article::class); //

    ϦϙδτϦܦ༝Ͱ // ID͕1ͷArticleΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1);  101 DB
  27. / 147 // ΤϯςΟςΟϚωʔδϟʔ͔Β // ArticleΤϯςΟςΟ༻ͷϦϙδτϦΛऔಘ $articleRepository = $entityManager->getRepository(Article::class); //

    ϦϙδτϦܦ༝Ͱ // ID͕1ͷArticleΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1);  102 DB Doctrine 色 💡
  28. / 147 // ΤϯςΟςΟϚωʔδϟʔ͔Β // ArticleΤϯςΟςΟ༻ͷϦϙδτϦΛऔಘ $articleRepository = $entityManager->getRepository(Article::class); //

    ϦϙδτϦܦ༝Ͱ // ID͕1ͷArticleΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1);  103 $entityManager
  29. / 147 // ΤϯςΟςΟϚωʔδϟʔ͔Β // ArticleΤϯςΟςΟ༻ͷϦϙδτϦΛऔಘ $articleRepository = $entityManager->getRepository(Article::class); //

    ϦϙδτϦܦ༝Ͱ // ID͕1ͷArticleΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1);  104 $entityManager
  30. / 147 #[Route('/article', name: 'article_')] class ArticleController extends AbstractController {

    #[Route('/', name: 'index', methods: ['GET'])] public function index(EntityManagerInterface $entityManager): Response { $articleRepository = $entityManager->getRepository(Article::class); // ... } }  105 DI Symfony
  31. / 147 #[Route('/article', name: 'article_')] class ArticleController extends AbstractController {

    #[Route('/', name: 'index', methods: ['GET'])] public function index(EntityManagerInterface $entityManager): Response { $articleRepository = $entityManager->getRepository(Article::class); // ... } }  106 DI Symfony
  32. / 147 #[Route('/article', name: 'article_')] class ArticleController extends AbstractController {

    #[Route('/', name: 'index', methods: ['GET'])] public function index(EntityManagerInterface $entityManager): Response { $articleRepository = $entityManager->getRepository(Article::class); // ... } }  107 DI Symfony DI 🙏
  33. / 147 // ΤϯςΟςΟϚωʔδϟʔ͔Β // ArticleΤϯςΟςΟ༻ͷϦϙδτϦΛऔಘ $articleRepository = $entityManager->getRepository(Article::class); //

    ϦϙδτϦܦ༝Ͱ // ID͕1ͷArticleΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1);  108
  34. / 147 // ΤϯςΟςΟϚωʔδϟʔ͔Β // ArticleΤϯςΟςΟ༻ͷϦϙδτϦΛऔಘ $articleRepository = $entityManager->getRepository(Article::class); //

    ϦϙδτϦܦ༝Ͱ // ID͕1ͷArticleΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1);  109 $articleRepository-> fi nd(1)
  35. / 147 // ID͕1ͷArticleΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1); // ͢΂ͯͷArticleΤϯςΟςΟͷ഑ྻΛऔಘ $articles

    = $articleRepository->findAll(); // ެ։ࡁΈͷArticleΤϯςΟςΟͷ഑ྻΛऔಘ $articles = $articleRepository->findBy(['published' => true]); // ެ։ࡁΈ͔ͭɺλΠτϧ͕ʮPHPΧϯϑΝϨϯε߳઒ʯͰ͋ΔArticleΤϯςΟςΟΛ1ͭऔಘ $article = $articleRepository->findOneBy([ 'published' => true, 'title' => 'PHPΧϯϑΝϨϯε߳઒', ]);  111
  36. / 147 // ID͕1ͷArticleΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1); // ͢΂ͯͷArticleΤϯςΟςΟͷ഑ྻΛऔಘ $articles

    = $articleRepository->findAll(); // ެ։ࡁΈͷArticleΤϯςΟςΟͷ഑ྻΛऔಘ $articles = $articleRepository->findBy(['published' => true]); // ެ։ࡁΈ͔ͭɺλΠτϧ͕ʮPHPΧϯϑΝϨϯε߳઒ʯͰ͋ΔArticleΤϯςΟςΟΛ1ͭऔಘ $article = $articleRepository->findOneBy([ 'published' => true, 'title' => 'PHPΧϯϑΝϨϯε߳઒', ]);  112
  37. / 147 // ެ։ࡁΈ͔ͭɺ // λΠτϧʹʮPHPΧϯϑΝϨϯε߳઒ʯΛؚΉArticleΤϯςΟςΟͷ഑ྻΛɺ // IDͷ߱ॱͰऔಘ $articles =

    $articleRepository->createQueryBuilder('a') ->where('a.published = :published') ->andWhere('a.title LIKE :query') ->orderBy('a.id', 'DESC') ->setParameter('published', true) ->setParameter('query', '%PHPΧϯϑΝϨϯε߳઒%') ->getQuery() ->getResult();  117
  38. / 147 // ެ։ࡁΈ͔ͭɺ // λΠτϧʹʮPHPΧϯϑΝϨϯε߳઒ʯΛؚΉArticleΤϯςΟςΟͷ഑ྻΛɺ // IDͷ߱ॱͰऔಘ $articles =

    $articleRepository->createQueryBuilder('a') ->where('a.published = :published') ->andWhere('a.title LIKE :query') ->orderBy('a.id', 'DESC') ->setParameter('published', true) ->setParameter('query', '%PHPΧϯϑΝϨϯε߳઒%') ->getQuery() ->getResult();  118 生 立 Article a
  39. / 147 // ެ։ࡁΈ͔ͭɺ // λΠτϧʹʮPHPΧϯϑΝϨϯε߳઒ʯΛؚΉArticleΤϯςΟςΟͷ഑ྻΛɺ // IDͷ߱ॱͰऔಘ $articles =

    $articleRepository->createQueryBuilder('a') ->where('a.published = :published') ->andWhere('a.title LIKE :query') ->orderBy('a.id', 'DESC') ->setParameter('published', true) ->setParameter('query', '%PHPΧϯϑΝϨϯε߳઒%') ->getQuery() ->getResult();  119 WHERE :published
  40. / 147 // ެ։ࡁΈ͔ͭɺ // λΠτϧʹʮPHPΧϯϑΝϨϯε߳઒ʯΛؚΉArticleΤϯςΟςΟͷ഑ྻΛɺ // IDͷ߱ॱͰऔಘ $articles =

    $articleRepository->createQueryBuilder('a') ->where('a.published = :published') ->andWhere('a.title LIKE :query') ->orderBy('a.id', 'DESC') ->setParameter('published', true) ->setParameter('query', '%PHPΧϯϑΝϨϯε߳઒%') ->getQuery() ->getResult();  120 WHERE :query
  41. / 147 // ެ։ࡁΈ͔ͭɺ // λΠτϧʹʮPHPΧϯϑΝϨϯε߳઒ʯΛؚΉArticleΤϯςΟςΟͷ഑ྻΛɺ // IDͷ߱ॱͰऔಘ $articles =

    $articleRepository->createQueryBuilder('a') ->where('a.published = :published') ->andWhere('a.title LIKE :query') ->orderBy('a.id', 'DESC') ->setParameter('published', true) ->setParameter('query', '%PHPΧϯϑΝϨϯε߳઒%') ->getQuery() ->getResult();  121 ORDER BY
  42. / 147 // ެ։ࡁΈ͔ͭɺ // λΠτϧʹʮPHPΧϯϑΝϨϯε߳઒ʯΛؚΉArticleΤϯςΟςΟͷ഑ྻΛɺ // IDͷ߱ॱͰऔಘ $articles =

    $articleRepository->createQueryBuilder('a') ->where('a.published = :published') ->andWhere('a.title LIKE :query') ->orderBy('a.id', 'DESC') ->setParameter('published', true) ->setParameter('query', '%PHPΧϯϑΝϨϯε߳઒%') ->getQuery() ->getResult();  122 :published :query
  43. / 147 // ެ։ࡁΈ͔ͭɺ // λΠτϧʹʮPHPΧϯϑΝϨϯε߳઒ʯΛؚΉArticleΤϯςΟςΟͷ഑ྻΛɺ // IDͷ߱ॱͰऔಘ $articles =

    $articleRepository->createQueryBuilder('a') ->where('a.published = :published') ->andWhere('a.title LIKE :query') ->orderBy('a.id', 'DESC') ->setParameter('published', true) ->setParameter('query', '%PHPΧϯϑΝϨϯε߳઒%') ->getQuery() ->getResult();  123 立
  44. / 147 // ެ։ࡁΈ͔ͭɺ // λΠτϧʹʮPHPΧϯϑΝϨϯε߳઒ʯΛؚΉArticleΤϯςΟςΟͷ഑ྻΛɺ // IDͷ߱ॱͰऔಘ $articles =

    $articleRepository->createQueryBuilder('a') ->where('a.published = :published') ->andWhere('a.title LIKE :query') ->orderBy('a.id', 'DESC') ->setParameter('published', true) ->setParameter('query', '%PHPΧϯϑΝϨϯε߳઒%') ->getQuery() ->getResult();  124 SQL 行
  45. / 147 // ެ։ࡁΈ͔ͭɺ // λΠτϧʹʮPHPΧϯϑΝϨϯε߳઒ʯΛؚΉArticleΤϯςΟςΟͷ഑ྻΛɺ // IDͷ߱ॱͰऔಘ $articles =

    $articleRepository->createQueryBuilder('a') ->where('a.published = :published') ->andWhere('a.title LIKE :query') ->orderBy('a.id', 'DESC') ->setParameter('published', true) ->setParameter('query', '%PHPΧϯϑΝϨϯε߳઒%') ->getQuery() ->getResult();  125
  46. / 147 // ެ։ࡁΈ͔ͭɺ // λΠτϧʹʮPHPΧϯϑΝϨϯε߳઒ʯΛؚΉArticleΤϯςΟςΟͷ഑ྻΛɺ // IDͷ߱ॱͰऔಘ $articles =

    $articleRepository->createQueryBuilder('a') ->where('a.published = :published') ->andWhere('a.title LIKE :query') ->orderBy('a.id', 'DESC') ->setParameter('published', true) ->setParameter('query', '%PHPΧϯϑΝϨϯε߳઒%') ->getQuery() ->getResult();  126
  47. / 147 // લఏͱͯ͠ϦϙδτϦ͔ΒΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1); // ී௨ʹΤϯςΟςΟͷ಺༰Λมߋ͢Ε͹ //

    Unit of Work͕ͦͷมߋ಺༰Λݕ஌͢Δ $article->title = '৽͍͠λΠτϧ'; // ͦͯ͠...  129 DB
  48. / 147 // લఏͱͯ͠ϦϙδτϦ͔ΒΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1); // ී௨ʹΤϯςΟςΟͷ಺༰Λมߋ͢Ε͹ //

    Unit of Work͕ͦͷมߋ಺༰Λݕ஌͢Δ $article->title = '৽͍͠λΠτϧ'; // ͦͯ͠... // มߋ಺༰ͷDB΁ͷ൓өΛґཔ $entityManager->flush();  130 DB
  49. / 147 // લఏͱͯ͠ϦϙδτϦ͔ΒΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1); // ී௨ʹΤϯςΟςΟͷ಺༰Λมߋ͢Ε͹ //

    Unit of Work͕ͦͷมߋ಺༰Λݕ஌͢Δ $article->title = '৽͍͠λΠτϧ'; // ͦͯ͠... // มߋ಺༰ͷDB΁ͷ൓өΛґཔ $entityManager->flush();  131 DB DB Unit of Work 💡
  50. / 147 // ΤϯςΟςΟΛ৽ن࡞੒ $article = new Article(); $article->title =

    'λΠτϧ'; // ΤϯςΟςΟΛUnit of Workʹ௥Ճ $entityManager->persist($article); // มߋ಺༰ͷDB΁ͷ൓өΛґཔ $entityManager->flush();  132
  51. / 147 // ΤϯςΟςΟΛ৽ن࡞੒ $article = new Article(); $article->title =

    'λΠτϧ'; // ΤϯςΟςΟΛUnit of Workʹ௥Ճ $entityManager->persist($article); // มߋ಺༰ͷDB΁ͷ൓өΛґཔ $entityManager->flush();  133 Unit of Work 行 🤦
  52. / 147 // ΤϯςΟςΟΛ৽ن࡞੒ʢ͜ͷ࣌఺Ͱ͸·ͩUnit of Workͷ؅ཧԼʹͳ͍ʣ $article = new Article();

    $article->title = 'λΠτϧ'; // ΤϯςΟςΟΛUnit of Workʹొ࿥ $entityManager->persist($article); // มߋ಺༰ʢ৽ن௥ՃΛؚΉʣͷDB΁ͷ൓өΛґཔ $entityManager->flush();  134 fl ush()
  53. / 147 // લఏͱͯ͠ϦϙδτϦ͔ΒΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1); // ͦͯ͠... //

    ΤϯςΟςΟΛ࡟আ͢ΔҙࢥΛUnit of Workʹ఻͑Δ $entityManager->remove($article); // มߋ಺༰ʢ࡟আΛؚΉʣͷDB΁ͷ൓өΛґཔ $entityManager->flush();  136
  54. / 147 // લఏͱͯ͠ϦϙδτϦ͔ΒΤϯςΟςΟΛऔಘ $article = $articleRepository->find(1); // ͦͯ͠... //

    ΤϯςΟςΟΛ࡟আ͢ΔҙࢥΛUnit of Workʹ఻͑Δ $entityManager->remove($article); // มߋ಺༰ʢ࡟আΛؚΉʣͷDB΁ͷ൓өΛґཔ $entityManager->flush();  137 Unit of Work
  55. / 147 // ΤϯςΟςΟΛ৽ن࡞੒ʢ͜ͷ࣌఺Ͱ͸·ͩUnit of Workͷ؅ཧԼʹͳ͍ʣ $article = new Article();

    $article->title = 'λΠτϧ'; // ΤϯςΟςΟΛ࡟আ͢ΔҙࢥΛUnit of Workʹ఻͑Δ $entityManager->remove($article); // มߋ಺༰ʢ࡟আΛؚΉʣͷDB΁ͷ൓өΛґཔ $entityManager->flush();  138
  56. / 147 // ΤϯςΟςΟΛ৽ن࡞੒ʢ͜ͷ࣌఺Ͱ͸·ͩUnit of Workͷ؅ཧԼʹͳ͍ʣ $article = new Article();

    $article->title = 'λΠτϧ'; // ΤϯςΟςΟΛ࡟আ͢ΔҙࢥΛUnit of Workʹ఻͑Δ $entityManager->remove($article); // มߋ಺༰ʢ࡟আΛؚΉʣͷDB΁ͷ൓өΛґཔ $entityManager->flush();  139 Unit of Work 示 行 ✋
  57. / 147 Doctrine Data Mapper 方 手 ・ 心 Doctrine

    Doctrine ・ Unit of Work ・ 3 方・ 方 方 ・ ・ 方 30  143
  58. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; }
  59. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; }
  60. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] #[ORM\Table(name: 'article')] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(name: 'id', type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(name: 'title', type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(name: 'content', type: Types::TEXT, nullable: true)] public ?string $content = null; }
  61. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(type: Types::TEXT, nullable: true)] public ?string $content = null; }
  62. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(type: Types::TEXT, nullable: true)] public ?string $content = null; } PHP PHP
  63. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column(type: Types::INTEGER)] public ?int $id = null; #[ORM\Column(type: Types::STRING, length: 255)] public ?string $title = null; #[ORM\Column(type: Types::TEXT, nullable: true)] public ?string $content = null; } PHP string DBAL text string 示
  64. /xxx ຊจϨϕϧ1 ຊจϨϕϧ2 ຊจϨϕϧ3 ຊจϨϕϧ4 ຊจϨϕϧ5 use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping

    as ORM; #[ORM\Entity] class Article { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] public ?int $id = null; #[ORM\Column(length: 255)] public ?string $title = null; #[ORM\Column(type: Types::TEXT, nullable: true)] public ?string $content = null; }
  65. / 147 #[Route('/article', name: 'article_')] class ArticleController extends AbstractController {

    #[Route('/', name: 'index', methods: ['GET'])] public function index(ArticleRepository $articleRepository): Response { // ... } }  164