Doctrine2 ORM を試してみます

エンティティクラスの作成

プロパティとマッピング情報を定義します。

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="products")
 */
class Product
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    protected $name;

    /**
     * @ORM\Column(type="decimal", scale=2)
     */
    protected $price;

    /**
     * @ORM\Column(type="text")
     */
    protected $description;
}

ゲッター・セッターの追加

デフォルト動作ではバックアップファイルを作ります。
バックアップがいらない場合は、no-backupオプションをつけます。

$ php app/console doctrine:generate:entities xxxxx/SampleBundle/Entity/Product
Generating entity "xxxxx\SampleBundle\Entity\Product"
  > backing up Product.php to Product.php~
  > generating xxxxx\SampleBundle\Entity\Product

スキーマの作成

エンティティクラスを基に、DBテーブルを作ります。dump-sqlオプションで、クエリを確認できます。

$ php app/console doctrine:schema:create --dump-sql
CREATE TABLE products (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(100) NOT NULL,
price NUMERIC(10, 2) NOT NULL, description LONGTEXT NOT NULL,
PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

// 本番環境では実行しないで、とのこと。
$ php app/console doctrine:schema:create
ATTENTION: This operation should not be executed in a production environment.

Creating database schema...
Database schema created successfully!

$ php app/console doctrine:schema:update --force
Nothing to update - your database is already in sync with the current entity metadata.

$ mysql -h localhost --protocol=tcp -u root -D symfony -p
mysql> show tables;
+-------------------+
| Tables_in_symfony |
+-------------------+
| ...               |
| products          |
| ...               |
+-------------------+

mysql> desc products;
+-------------+---------------+------+-----+---------+----------------+
| Field       | Type          | Null | Key | Default | Extra          |
+-------------+---------------+------+-----+---------+----------------+
| id          | int(11)       | NO   | PRI | NULL    | auto_increment |
| name        | varchar(100)  | NO   |     | NULL    |                |
| price       | decimal(10,2) | NO   |     | NULL    |                |
| description | longtext      | NO   |     | NULL    |                |
+-------------+---------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)

サンプルコードを書いて実験

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use xxxxx\SampleBundle\Entity\Product;

class TestDoctrineOrmCommand extends ContainerAwareCommand
{

    protected function configure()
    {
        $this->setName('sample:doctrine');
        $this->setDescription('Doctrine2 ORMを試します');
    }

    protected function doSomething(Product $product)
    {
        $product->setName('ドイツパン');
        $product->setPrice('380');
        $product->setDescription('美味しいけど高い');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $product = new Product();
        $product->setName('くるみパン');
        $product->setPrice('130');
        $product->setDescription('美味しい');

        // エンティティマネージャを取得
        $em = $this->getContainer()->get('doctrine')->getManager();
        // エンティティマネージャにproductオブジェクトを監視させる
        $em->persist($product);

        $this->doSomething($product);

        // 永続化の必要性を判断し、必要があればクエリが発行される
        $em->flush();

        $em->close();
    }
}

$ php app/console sample:doctrine --env=dev

$ cat app/logs/dev.log
[2014-06-21 00:24:16] doctrine.DEBUG: "START TRANSACTION" [] []
[2014-06-21 00:24:16] doctrine.DEBUG: INSERT INTO products (name, price, description) VALUES (?, ?, ?) {"1":"ドイツパン","2":"380","3":"美味しいけど高い"} []
[2014-06-21 00:24:16] doctrine.DEBUG: "COMMIT" [] []

mysql> select * from products;
+----+-----------------+--------+--------------------------+
| id | name            | price  | description              |
+----+-----------------+--------+--------------------------+
|  1 | ドイツパン      | 380.00 | 美味しいけど高い         |
+----+-----------------+--------+--------------------------+
1 row in set (0.00 sec)

$ php app/console doctrine:query:dql "SELECT p FROM xxxxx\SampleBundle\Entity\Product p WHERE p.id = 1"
array (size=1)
  0 =>
    object(stdClass)[367]
      public '__CLASS__' => string 'xxxxx\SampleBundle\Entity\Product' (length=xx)
      public 'id' => int 1
      public 'name' => string 'ドイツパン' (length=15)
      public 'price' => string '380.00' (length=6)
      public 'description' => string '美味しいけど高い' (length=24)