Doctrine ORMとは?
Doctrine ORMは、PHPのオブジェクトとデータベースのテーブルをマッピングするライブラリです。SQLを直接書かなくても、PHPのクラス(エンティティ)を通じてデータベース操作ができます。
SymfonyはDoctrine ORMと非常に密接に統合されており、Symfonyプロジェクトでは標準的なデータベースアクセス手段として利用されています。
この記事では以下の流れで解説します。
- エンティティの作成
- マイグレーションの実行
- リポジトリを使ったCRUD操作
セットアップ
まずDoctrineをインストールします。
composer require symfony/orm-pack
composer require --dev symfony/maker-bundle
次に.envファイルでデータベース接続情報を設定します。
DATABASE_URL="mysql://root:password@127.0.0.1:3306/symfony_demo?serverVersion=8.0"
データベースを作成します。
php bin/console doctrine:database:create
エンティティを作成する
エンティティとは、データベースのテーブルに対応するPHPクラスです。Makerバンドルを使うと対話形式で簡単に生成できます。
php bin/console make:entity Article
コマンドを実行すると、フィールド名や型を対話的に入力できます。以下のようなArticleエンティティが生成されます。
// src/Entity/Article.php
namespace App\Entity;
use App\Repository\ArticleRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ArticleRepository::class)]
class Article
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $title = null;
#[ORM\Column(type: 'text')]
private ?string $body = null;
#[ORM\Column]
private ?\DateTimeImmutable $createdAt = null;
// getterとsetter(省略)
public function getId(): ?int { return $this->id; }
public function getTitle(): ?string { return $this->title; }
public function setTitle(string $title): static
{
$this->title = $title;
return $this;
}
public function getBody(): ?string { return $this->body; }
public function setBody(string $body): static
{
$this->body = $body;
return $this;
}
public function getCreatedAt(): ?\DateTimeImmutable { return $this->createdAt; }
public function setCreatedAt(\DateTimeImmutable $createdAt): static
{
$this->createdAt = $createdAt;
return $this;
}
}
#[ORM\Column]などのPHP 8のアトリビュート(Attribute)でカラムの定義を行います。
マイグレーションを実行する
エンティティを作成したら、その内容をデータベースに反映します。
# マイグレーションファイルを生成
php bin/console make:migration
# マイグレーションを実行
php bin/console doctrine:migrations:migrate
生成されたマイグレーションファイルはmigrations/ディレクトリに保存されます。中身はこのようなSQLを含むPHPファイルです。
public function up(Schema $schema): void
{
$this->addSql('CREATE TABLE article (
id INT AUTO_INCREMENT NOT NULL,
title VARCHAR(255) NOT NULL,
body LONGTEXT NOT NULL,
created_at DATETIME NOT NULL COMMENT "(DC2Type:datetime_immutable)",
PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8mb4');
}
マイグレーションを使うことでデータベースの変更履歴が管理でき、チーム開発や本番環境への適用がスムーズになります。
リポジトリでCRUD操作を行う
リポジトリはデータベースへのクエリをまとめるクラスです。エンティティを作成するとArticleRepositoryも自動生成されます。
データの保存(Create)
// src/Controller/ArticleController.php
use App\Entity\Article;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
#[Route('/article/new', name: 'article_new')]
public function new(EntityManagerInterface $em): Response
{
$article = new Article();
$article->setTitle('はじめての記事');
$article->setBody('Doctrine ORMは便利です!');
$article->setCreatedAt(new \DateTimeImmutable());
$em->persist($article); // 保存対象として登録
$em->flush(); // 実際にINSERTを発行
return new Response('記事ID: ' . $article->getId());
}
}
データの取得(Read)
#[Route('/article/{id}', name: 'article_show')]
public function show(int $id, ArticleRepository $repo): Response
{
// プライマリキーで1件取得
$article = $repo->find($id);
if (!$article) {
throw $this->createNotFoundException('記事が見つかりません');
}
return new Response($article->getTitle());
}
リポジトリには便利なメソッドが標準で用意されています。
// 全件取得
$articles = $repo->findAll();
// 条件で検索
$articles = $repo->findBy(['title' => 'テスト'], ['createdAt' => 'DESC']);
// 1件だけ条件で検索
$article = $repo->findOneBy(['title' => 'はじめての記事']);
カスタムクエリ(QueryBuilder)
より複雑な検索はリポジトリにメソッドを追加します。
// src/Repository/ArticleRepository.php
public function findRecent(int $limit = 5): array
{
return $this->createQueryBuilder('a')
->orderBy('a.createdAt', 'DESC')
->setMaxResults($limit)
->getQuery()
->getResult();
}
データの更新(Update)と削除(Delete)
// Update
$article = $repo->find(1);
$article->setTitle('タイトルを変更しました');
$em->flush(); // flushするだけでUPDATEが発行される
// Delete
$article = $repo->find(1);
$em->remove($article);
$em->flush();
まとめ
この記事では、Symfony + Doctrine ORMの基本的な使い方を解説しました。
| 操作 | メソッド |
|---|---|
| 保存 | persist() + flush() |
| 取得 | find() / findBy() |
| 更新 | プロパティ変更 + flush() |
| 削除 | remove() + flush() |
Doctrine ORMを使うことで、SQLを直接書かずに安全・簡潔にデータベース操作ができます。次のステップとして、エンティティ間のリレーション(OneToMany・ManyToManyなど)を学ぶとさらに表現力が広がります。ぜひ試してみてください!