英語がきっちり訳せず理解できず変な部分もあるので、公開後も修正していくと思います (||´ロ`)o
ではでは始めていきます( -_-)ノ
Getting Started with Doctrine
以下のことがわかるらしい
・ Doctrine ORMの
インスコと構成の仕方
・ EntityManagerを使ってDBに
CRUD操作をする
Guide Assumptions
Doctirine ORM使ったことないビギナー向け。
以下は必要
・ composer
What is Doctrine?
Doctrine2はPHP5.4以上に向けて提供されるORM、
ビジネスロジックと
DBMSの完全な分離を目的に作られています。
Doctrineを使う利点は
オブジェクト指向における
ビジネスロジックに集中する事ができ、永続性に関しての不安を二の次にすることが出来ます。(これはDoctrine2が永続化を過小評価してるわけではありません。)ただ、永続化とエンティティが分離されていれば、
OOPに利益をもたらすと信じています。
What are Entities?
エンティティとはプライマリキーやユニークな指定詞によって、多くのリクエストを実行できる
PHPのオブジェクトです。これらのクラスは抽象クラスやインターフェースを拡張する必要はなく、finalのついた
メソッドであってはなりません。
An Example Model: Bug Tracker
Zend Db TableのドキュメントにあるBag Tracker domain modelを利用するらしい。
詳細は書きませんが、どうやらユーザがバグのレポートをエンジニアに対して出し、エンジニアが解決したらレポートを閉じるようなシステムを想定しているようです。
システムの内容云々は今回はいいので、進めていきます。
Project Setup
{
"require": {
"doctrine/orm": "2.4.*",
"symfony/yaml": "2.*"
},
"autoload": {
"psr-0": {"": "src/"}
}
}
をcomposer.
jsonに書いて、composer install します。
でcomposer.pharを落としてきます。
チュートリ通り、以下のディレクトリを加えます
doctrine2-tutorial
|-- config
| |-- xml
| `-- yaml
`-- src
Obtaining the EntityManager
DoctrineのインターフェースはEntityManagerで、エンティティと永続化部分のライフサイクルマネジメントのアクセスポイントを提供しているらしい。自分のエンティティをdoctrineで構成し作成する必要があるようです。まずは作成し、徐々に議論していくらしいので、とにかく写経していきます。
<?php
// bootstrap.php
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
require_once "vendor/autoload.php";
// Create a simple "default" Doctrine ORM configuration for Annotations
$isDevMode = true;
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode);
// or if you prefer yaml or XML
//$config = Setup::createXMLMetadataConfiguration(array(__DIR__."/config/xml"), $isDevMode);
//$config = Setup::createYAMLMetadataConfiguration(array(__DIR__."/config/yaml"), $isDevMode);
// database configuration parameters
$conn = array(
'driver' => 'pdo_sqlite',
'path' => __DIR__ . '/db.sqlite',
);
// obtaining the entity manager
$entityManager = EntityManager::create($conn, $config);
詳細は大したことないので、省略。
sqliteじゃなくて
mysqlにしたいので、dbalのドキュメントに従って、$conn = …の部分を以下にしてみます。
$conn = array(
‘dbname’ => ‘dtest',
‘user’ => ‘silex’,
‘password’ => ‘password’,
);
Generating the Database Schema
cli-config.
phpをルートディレクトリに作って実行してみます。
<?php
// cli-config.php
require_once "bootstrap.php";
return \Doctrine\ORM\Tools\Console\ConsoleRunner::createHelperSet($entityManager);
実行コマンド
$ cd project/
$ vendor/bin/doctrine orm:schema-tool:create
説明でもあるようにNo Metadata Classes to processが出てもDon’t worry!!
次の章でやってくれるらしい。個々ではエンティティの
メタデータがDB
スキーマと同期されてることが大事だと気づけばいいそうです。
以下のコマンドで、recreateできます。
$ vendor/bin/doctrine orm:schema-tool:drop --force
$ vendor/bin/doctrine orm:schema-tool:create
もしくはupdateを使います
$ vendor/bin/doctrine orm:schema-tool:update --force
Starting with the Product
ドキュメントに従って、productエンティティの定義から始めます。src/Product.
phpに以下を作成します。
<?php
// src/Product.php
class Product
{
/**
* @var int
*/
protected $id;
/**
* @var string
*/
protected $name;
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
}
idのセット以外はgetterとsetter(mutator)を作って定義します基本的にidに対してはsetterをかく必要はないようです。次にProductエンティティの構造をDoctrineの
メタデータ言語を使って定義します。フィールド定義の部分を以下のようにします。
<?php
// src/Product.php
/**
* @Entity @Table(name="products")
**/
class Product
{
/** @Id @Column(type="integer") @GeneratedValue **/
protected $id;
/** @Column(type="string") **/
protected $name;
// .. (other code)
}
クラス名がDBのテーブル名に、フィールド名がDBの
カラム名に対応していることがわかります。ここでDBの構成をアップデートします。
$ vendor/bin/doctrine orm:schema-tool:update --force --dump-sql
実行すると
CREATE TABLE products (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
Updating database schema...
Database schema updated successfully! "1" queries were executed
と結果が返り、dtestデータベースにProductsテーブルが無事出来ていました!いい!
ここで新しい
スクリプトでDBにレコードを追加してみます。
<?php
// create_product.php
require_once "bootstrap.php";
$newProductName = $argv[1];
$product = new Product();
$product->setName($newProductName);
$entityManager->persist($product);
$entityManager->flush();
echo "Created Product with ID " . $product->getId() . "\n";
persist()とflush()が分離されていることで、flushが呼ばれたときにすべての
トランザクションを実行することが可能になっているのがわかります。これを利用することでDBに対する書き込みのパフォーマンスが格段に良くなるそうです。DoctrineはUnitOfWorkパターンに従うことでエンティティへの変更を検出できるようにしているそうです。
次のステップとして、すべてのプロダクトリストをフェッチしてみます。
<?php
// list_products.php
require_once "bootstrap.php";
$productRepository = $entityManager->getRepository('Product');
$products = $productRepository->findAll();
foreach ($products as $product) {
echo sprintf("-%s\n", $product->getName());
}
EntityManagerのgetRepository()
メソッドはエンティティごとのfinderオブジェクトを作成することができ、Doctrineによって提供されるfindAll()などの
メソッドを使えるようになります。
<?php
// show_product.php <id>
require_once "bootstrap.php";
$id = $argv[1];
$product = $entityManager->find('Product', $id);
if ($product === null) {
echo "No product found.\n";
exit(1);
}
echo sprintf("-%s\n", $product->getName());
続けてIDに従ってプロダクトの名前を表示してみます。UnitOfWorkパターンを使うことでエンティティを見つけるだけでそれらの変更はDBに適用してくれます。
<?php
// update_product.php <id> <new-name>
require_once "bootstrap.php";
$id = $argv[1];
$newName = $argv[2];
$product = $entityManager->find('Product', $id);
if ($product === null) {
echo "Product $id does not exist.\n";
exit(1);
}
$product->setName($newName);
$entityManager->flush();
この
スクリプトを存在するプロダクトに対して呼んだ後、show_product.
phpスクリプトを呼ぶことでプロダクトの名前を変更することができます。
コード量も多くないですし、実行結果も想像がつくのでここでは試さず次にいこうと思います。
と思いましたがエンティティによってDBを操作することが出来たここまでで次回に続けます。
TSUDUKU ⊂゚U┬───┬~