35歳からの中二病エンジニア

社寺・鉄道・アニメを愛でるウェブ技術者の呟き

LaravelのORMとしてDoctrineを使う

新規サービスでLaravelを採用するにあたり、標準のORMであるEloquentを学習しようかとも考えたが、Doctrineに載せ替えればアノテーションでスラスラとスキーマ定義できるし、DDDとの親和性も高いので、うまく導入できる方法を調べてみた。

Laravel Doctrine

www.laraveldoctrine.org

出オチとなってしまうが、その名の通りのパッケージがあった。これをComposerでインストールする。migrationsとextensionsは別パッケージになっているが、どちらもDoctrineを本格活用する上で必須となるため、同時に導入しておきたい。

composer require "laravel-doctrine/orm:1.2.*"
composer require "laravel-doctrine/migrations:1.0.*"
composer require "laravel-doctrine/extensions:1.0.*"
composer require "gedmo/doctrine-extensions=^2.4"

なお、インストールや利用方法の詳細は公式ドキュメントが詳しいのでそちらを参照していただくとして、ここでは押さえておきたいポイントを掻い摘まんでいくこととする。

Artisanコマンドとの連携

これはSynfonyでDoctrineを扱う感覚そのままと言っても差し支えないほどによくできている。proxyクラスの生成からマイグレーションまで完璧に揃っているので、そのままで十分に実用可能だ。参考までに、ORM、Migrations、Extensionsの各パッケージを導入した場合に利用できるArtisanコマンドを以下に挙げる。

doctrine:clear:metadata:cache
doctrine:migrations:generate
doctrine:migrations:rollback
doctrine:migrations:refresh
doctrine:migrations:version
doctrine:clear:result:cache
doctrine:migrations:execute
doctrine:migrations:migrate
doctrine:migrations:latest
doctrine:migrations:status
doctrine:generate:entities
doctrine:ensure:production
doctrine:clear:query:cache
doctrine:migrations:reset
doctrine:generate:proxies
doctrine:convert:mapping
doctrine:migrations:diff
doctrine:schema:validate
doctrine:mapping:import
doctrine:config:convert
doctrine:schema:create
doctrine:schema:update
doctrine:dump:sqlite
doctrine:schema:drop
doctrine:info

Debugbarとの連携

LaravelのDebugbarを利用している場合、SQLのクエリーログは手放せないだろう。だが、当然ながらORMをDoctrineに置き換えれば、そのままでは使えなくなってしまう。

…と思っていたのだけれども、ありがたいことにLaravel Doctrineは標準でログの吐き出し先を指定できるようになっており、Debugbarとも、そして先の記事で触れたClockworkとも連携できるようになっている!

return [
    /*
    |--------------------------------------------------------------------------
    | Enable query logging with laravel file logging,
    | debugbar, clockwork or an own implementation.
    | Setting it to false, will disable logging
    |
    | Available:
    | - LaravelDoctrine\ORM\Loggers\LaravelDebugbarLogger
    | - LaravelDoctrine\ORM\Loggers\ClockworkLogger
    | - LaravelDoctrine\ORM\Loggers\FileLogger
    |--------------------------------------------------------------------------
    */
    'logger'                    => env('DOCTRINE_LOGGER', false),
];

このように.envで簡単に切り替えられるようになっているため、迷うことは無いだろう。

IDE補完

LaravelはIDE補完が優秀だが、その恩恵はDoctrineに切り替えても基本的に受けられる。find系のメソッドで取ってきたEntity等もバッチリである。ただ、今の所Repositoryに追加したメソッドについては補完の方法がわかっておらず、ここは大きな課題である。

Eloquentに対するデメリット

性能面はチューニングによっても変わってくるので触れないものとして、特に標準のEloquentと比べて劣ると感じた箇所は無かった(本格的にEloquentを触ったわけではないが)。ただORMとしての方向性は全く違うので、用途に応じて使い分ける必要はあるだろう。

おわりに

Laravel Doctrineを使えば、Synfony上で使うのと似たような感覚で便利にDoctrineを扱うことができる。現状だと日本語の情報は皆無に等しいが、公式ドキュメントが充実しているため導入には困らないだろう。Eloquentの代替となるORMの選択肢としては、十分検討に値するものと思われる。