エンティティマッピング
Weaver ORM は、すべてのマッピング情報を専用のマッパークラスに配置することで、ドメインオブジェクトと永続化メタデータを分離します。このページではマッパー設定のすべての側面を説明します。
アトリビュートではなくマッパーを使う理由
Doctrine ORM は PHP 8 アトリビュートを通じてマッピングメタデータをエンティティクラスに直接配置します:
// Doctrine のアプローチ — エンティティがデータベースを知っている
#[ORM\Entity]
#[ORM\Table(name: 'users')]
class User
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private int $id;
}
Weaver はそれらを厳密に分離します:
エンティティクラス → 純粋な PHP オブジェクト、ORM 依存ゼロ
マッパークラス → すべての永続化知識はここに
利点:
- 実行時リフレクションゼロ。 マッパーは配列とスカラーを返す純粋な PHP です。
- プロキシクラスなし。 ディスク上のコード生成が不要です。
- ワーカーセーフ。 マッパーはリクエストごとの状態を持ちません。
- 独立したテスト可能性。 Symfony を起動せずにユニットテストでマッパーをインスタンス化して検査できます。
- 完全に grep 可能。 すべてのカラム名、型、オプションはプレーンテキストで表示され、
git diffに現れます。
マッパーとエンティティ:責務
| 関心事 | 配置場所 |
|---|---|
| ビジネスロジック、不変条件 | エンティティクラス |
| プロパティと PHP 型 | エンティティクラス |
| テーブル名とスキーマ | マッパー |
| カラム名、型、オプション | マッパー |
| インデックスと制約 | マッパー |
| ハイドレーション(行 → エンティティ) | マッパー |
| 抽出(エンティティ → 行) | マッパー |
| リレーション | マッパー |
基本的なエンティティ定義
エンティティは任意の PHP クラスです。何も継承せず、何も実装せず、Weaver\ORM から何もインポートしません。
<?php
// src/Entity/User.php
declare(strict_types=1);
namespace App\Entity;
use DateTimeImmutable;
final class User
{
public function __construct(
public readonly ?int $id,
public readonly string $name,
public readonly string $email,
public readonly bool $isActive,
public readonly DateTimeImmutable $createdAt,
) {}
public function withEmail(string $email): self
{
return new self(
id: $this->id,
name: $this->name,
email: $email,
isActive: $this->isActive,
createdAt: $this->createdAt,
);
}
}
エンティティは以下のいずれかにできます:
- イミュータブル(推奨)— ミューテーションメソッドは新しいインスタンスを返す
- ミュータブル — パブリックプロパティまたはセッターも可
- 抽象 — 継承階層のため