BEAR.SundayでDoctrine2のORMを使ってみた(改)
77webさんの「BEAR.SundayでDoctrine2のORMを使ってみた」を試しつつ、少しだけ改良してみます。
BEAR.Sundayのインストール
ベンダー名はMy
、アプリケーション名はNote
とします。これらの指定は名前空間で使われます。
$ composer create-project bear/skeleton My.Note dev-develop
$ cd My.Note
$ composer install
なお、ここではdev-develop
を指定して開発ブランチ(developブランチ)をインストールしています。
Doctrineのインストール
$ composer require 'doctrine/orm:2.4.*'
データベース接続設定
BEAR.Sundayではデータベース接続設定はvar/conf/constants.phpで定義します。
具体的にはデフォルトで以下のようになっています。
var/conf/constants.php
$masterDb = $slaveDb = require __DIR__ .'/db/sqlite.php';
//list($masterDb, $slaveDb) = require __DIR__ .'/db/mysql.php';
return [
'prod' => [
// optional
'master_db' => $masterDb,
'slave_db' => $slaveDb,
],
'dev' => [],
'api' => [],
'test' => []
];
$masterDb
と$slaveDb
が定義されていますが、いずれもdb/sqlite.php
が代入されています。
prod
環境(本番環境)でこれらのデータベースが指定されていますが、prod
環境の設定が他の環境にも引き継がれるため、デフォルトではすべての環境でのデータベース接続設定は同じになっています。
db/sqlite.php
では具体的には以下のように定義されています。
var/db/sqlite.php
$sqlite = [
'driver' => 'pdo_sqlite',
'path' => $appDir . '/var/db/posts.sq3'
];
つまり、var/db/posts.sq3
が使用されるSQLiteのデータベースファイルということになります。
ここでは、デフォルトのままにします。
Providerの作成
DoctrineのEntityManagerを返すProviderを作成します。
とりあえず、マスターとスレーブの切り替えは考慮しません。
src/Module/Provider/DoctrineORMProvider.php
<?php
namespace My\Note\Module\Provider;
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
use Ray\Di\ProviderInterface;
use Ray\Di\Di\Inject;
use Ray\Di\Di\Named;
class DoctrineORMProvider implements ProviderInterface
{
/**
* @param array $masterDb
*
* @Inject
* @Named("masterDb=master_db")
*/
public function __construct(array $masterDb)
{
$this->masterDb = $masterDb;
}
public function get()
{
$paths = [__DIR__.'/../../Entity'];
$isDevMode = false;
$config = Setup::createAnnotationMetadataConfiguration(
$paths, $isDevMode
);
$conn = $this->masterDb;
return EntityManager::create($conn, $config);
}
}
コンストラクタインジェクションでデータベース接続設定のmaster_db
をプロパティに代入しています。
Providerのインストール
DoctrineORMProviderを使うようにインストールします。
My\Note\Module\AppModule
クラスのconfigure()
メソッドの最後に以下を追加します。
src/Module/AppModule.php
$this->bind('Doctrine\ORM\EntityManager')->toProvider('My\Note\Module\Provider\DoctrineORMProvider');
Entityの作成
Entityを作成します。
src/Entity/Note.php
<?php
namespace My\Note\Entity;
/**
* @Entity
* @Table(name="note")
*/
class Note
{
/**
* @var int
* @Id
* @Column(type="integer")
* @GeneratedValue
*/
private $id;
/**
* @var string
* @Column(type="text")
*/
private $body;
public function getId() {
return $this->id;
}
public function getBody() {
return $this->body;
}
public function setId($id) {
$this->id = $id;
}
public function setBody($body) {
$this->body = $body;
}
}
doctrineコマンドを使えるようにする
cli-config.phpをプロジェクトのルートディレクトリに作成します。
<?php
error_reporting(E_ALL);
ini_set('xdebug.max_nesting_level', 300);
require __DIR__ . '/bootstrap/autoload.php';
use My\Note\Module\AppModule;
use Ray\Di\Injector;
use Doctrine\ORM\Tools\Console\ConsoleRunner;
$module = new AppModule();
$injector = Injector::create([$module]);
$entityManager = $injector->getInstance('Doctrine\ORM\EntityManager');
return ConsoleRunner::createHelperSet($entityManager);
テーブルの作成
doctrineコマンドでテーブルを作成します。
$ php vendor/bin/doctrine orm:schema-tool:create
テストデータの登録
とりあえず、sqlite3コマンドでinsertしておきます。
$ sqlite3 var/db/posts.sq3
> insert into note(body) values('test body1');
> insert into note(body) values('test body2');
> .exit
Appリソースの作成
AppリソースNoteを作成します。
src/Resource/App/Note.php
<?php
namespace My\Note\Resource\App;
use BEAR\Resource\ResourceObject;
use Doctrine\ORM\EntityManager;
use Ray\Di\Di\Inject;
class Note extends ResourceObject
{
/**
* @var EntityManager
*/
private $entityManager;
/**
* @param EntityManager $entityManager
* @Inject
*/
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function onGet($id)
{
$note = $this->entityManager->find('My\Note\Entity\Note', $id);
$this['note'] = ['body' => $note->getBody()];
return $this;
}
}
コンストラクタインジェクションでEntityManagerをプロパティに代入しています。
Noteリソースの取得
CLIからNoteリソースを取得してみます。
$ php bootstrap/contexts/api.php get 'app://self/note?id=1'
200 OK
content-type: ["application\/hal+json; charset=UTF-8"]
cache-control: ["no-cache"]
date: ["Fri, 11 Jul 2014 03:48:55 GMT"]
[BODY]
note => array(
body test body1,
),
[VIEW]
{
"note": {
"body": "test body1"
},
"_links": {
"self": {
"href": "http://localhost/app/note/?id=1"
}
}
}
うまく取得できました!
参考
Date: 2014/07/11