こんにちわ!@mrtryです。 もう3月ですね。新卒入社して、もうすぐ1年経ちます。 新卒と言えなくなってしまうのが、ちょっと寂しい今日このごろです。
さて、「Symfony2入門」の7回目の記事です。 前回のSymfony2で利用されているDoctrineに入門する(前編)に引き続き、今日は中編をお送りします。
前回は、Doctrineについてざっくり紹介しました。
今回は、DoctrineとDBを連携するための設定
エンティティの作成
エンティティを元したテーブル作成
を紹介したいと思います。
プロジェクトをつくる
まず、準備として、Symfonyのプロジェクトをつくります。
今回はtry-doctrine
という名前で作成します。
$ symfony new try-doctrine 2.8 Downloading Symfony... 5.29 MB/5.29 MB ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 100% Preparing project... ✔ Symfony 2.8.15 was successfully installed. Now you can: * Change your current directory to /Users/symmt/Program/Study/try-doctrine * Configure your application in app/config/parameters.yml file. * Run your application: 1. Execute the php app/console server:run command. 2. Browse to the http://localhost:8000 URL. * Read the documentation at http://symfony.com/doc
RDBの設定
エンティティを生成する前に、DBの設定を行います。 今回は、RDBとしてmysqlを用いて実例を紹介します。
まず、app/config/parameters.yml
にて、設定を行います。
このファイルは、Symfonyのインフラに関係する設定をするためのファイルです。
各Bundleの設定や、APIのURLなどの定数の管理などに利用されます。
プロジェクトを立ち上げた直後のparameters.yml
にはDBとメールサーバーの設定が記述されています。
今回はdatabase_name
の箇所をtry-doctrine
と書き換えたものを利用します。
$ cat -n app/config/parameters.yml 1 # This file is auto-generated during the composer install 2 parameters: 3 database_host: 127.0.0.1 4 database_port: null 5 database_name: try-doctrine 6 database_user: root 7 database_password: null 8 mailer_transport: smtp 9 mailer_host: 127.0.0.1 10 mailer_user: null 11 mailer_password: null 12 secret: 328b4f9d66009015aa9e8770eb73163d0b74684f
設定が終わったら、doctrine:database:create
コマンドを実行します。
実行すると、database_name
で設定した名前でDBが新しく作成されます。
$ app/console doctrine:database:create Created database `try-doctrine` for connection named default
実際に一覧を見てみると、DBが作成されていることが確認できます。
mysql> show databases; +---------------------------+ | Database | +---------------------------+ | ... | | try-doctrine | +---------------------------+ 11 rows in set (0.01 sec)
エンティティを生成する
次に、エンティティを生成します。
doctrine:generate:entity
というコマンドを利用します。
実行すると対話形式となり、一通り入力が完了すると、エンティティが生成されます。
今回は例として、Product
というエンティティを生成したいと思います。
フィールド名等については、以下の表をご確認ください。
フィールド名 | 型 | null許容 | 主キー |
---|---|---|---|
id | id | false | true |
name | string(255) | false | false |
price | integer | false | false |
description | text | false | false |
実際に生成する
上記の表に沿って、エンティティを生成した際の様子です。
$ app/console doctrine:generate:entity Welcome to the Doctrine2 entity generator This command helps you generate Doctrine2 entities. First, you need to give the entity name you want to generate. You must use the shortcut notation like AcmeBlogBundle:Post. The Entity shortcut name: AppBundle:Product Determine the format to use for the mapping information. Configuration format (yml, xml, php, or annotation) [annotation]: Instead of starting with a blank entity, you can add some fields now. Note that the primary key will be added automatically (named id). Available types: array, simple_array, json_array, object, boolean, integer, smallint, bigint, string, text, datetime, datetimetz, date, time, decimal, float, binary, blob, guid. New field name (press <return> to stop adding fields): name Field type [string]: Field length [255]: Is nullable [false]: Unique [false]: New field name (press <return> to stop adding fields): price Field type [string]: integer Is nullable [false]: Unique [false]: New field name (press <return> to stop adding fields): description Field type [string]: text Is nullable [false]: Unique [false]: New field name (press <return> to stop adding fields): Entity generation created ./src/AppBundle/Entity/Product.php > Generating entity class src/AppBundle/Entity/Product.php: OK! > Generating repository class src/AppBundle/Repository/ProductRepository.php: OK! Everything is OK! Now get to work :).
各項目について
First, you need to give the entity name you want to generate. You must use the shortcut notation like AcmeBlogBundle:Post. The Entity shortcut name: AppBundle:Product
生成するエンティティ名とそれを置くBundle先をBundle名:エンティティ名
という書き方で指定します。
今回はAppBundle
にProduct
というエンティティを生成するので、AppBundle:Product
と書きました。
Determine the format to use for the mapping information. Configuration format (yml, xml, php, or annotation) [annotation]:
マッピング定義のフォーマットを指定します。
マッピング定義とはアプリケーション内のクラス、プロパティと、DBのテーブル、カラムの対応関係を定義しているものです。
ざっくりなイメージとしては、 ER図の内容を設定ファイルとしたものといった感じです。
デフォルトでは、annotation
で設定するようになっています。
今回はannotation
でよかったので、そのままReturnで進めました。
Instead of starting with a blank entity, you can add some fields now. Note that the primary key will be added automatically (named id).
IDの項目はDoctrine側で自動的に生成されます。
今回で言うと、id
がそれにあたります。
Available types: array, simple_array, json_array, object, boolean, integer, smallint, bigint, string, text, datetime, datetimetz, date, time, decimal, float, binary, blob, guid. New field name (press <return> to stop adding fields): name Field type [string]: Field length [255]: Is nullable [false]: Unique [false]: New field name (press <return> to stop adding fields): price Field type [string]: integer Is nullable [false]: Unique [false]: New field name (press <return> to stop adding fields): description Field type [string]: text Is nullable [false]: Unique [false]:
フィールド名とその型を設定していきます。
型は、Available types
にて列挙されているものを指定できます。
フィールド名 | 型 | null許容 | ユニークキー制約 |
---|---|---|---|
name | string | false | false |
price | integer | false | false |
description | text | false | false |
入力が終わったら、New field name (press <return> to stop adding fields)
と書いてあるとおり、フィールド名を入力せずReturnを押すと、次に進みます。
Entity generation created ./src/AppBundle/Entity/Product.php > Generating entity class src/AppBundle/Entity/Product.php: OK! > Generating repository class src/AppBundle/Repository/ProductRepository.php: OK! Everything is OK! Now get to work :).
ここまで終えると、エンティティとリポジトリが生成されます。 生成されたエンティティは以下のようになります。 先程設定していたフィールドがプロパティとして書かれ、プロパティの上部には設定した型などの情報がannotationで書かれていることが確認できます。 (突然出てきたリポジトリですが、今回は置いときます)
$ cat -n src/AppBundle/Entity/Product.php 1 <?php 2 3 namespace AppBundle\Entity; 4 5 use Doctrine\ORM\Mapping as ORM; 6 7 /** 8 * Product 9 * 10 * @ORM\Table(name="product") 11 * @ORM\Entity(repositoryClass="AppBundle\Repository\ProductRepository") 12 */ 13 class Product 14 { 15 /** 16 * @var int 17 * 18 * @ORM\Column(name="id", type="integer") 19 * @ORM\Id 20 * @ORM\GeneratedValue(strategy="AUTO") 21 */ 22 private $id; 23 24 /** 25 * @var string 26 * 27 * @ORM\Column(name="name", type="string", length=255) 28 */ 29 private $name; 30 31 /** 32 * @var int 33 * 34 * @ORM\Column(name="price", type="integer") 35 */ 36 private $price; 37 38 /** 39 * @var string 40 * 41 * @ORM\Column(name="description", type="text") 42 */ 43 private $description; 44 45 46 /** 47 * Get id 48 * 49 * @return integer 50 */ 51 public function getId() 52 { 53 return $this->id; 54 } 55 56 /** 57 * Set name 58 * 59 * @param string $name 60 * @return Product 61 */ 62 public function setName($name) 63 { 64 $this->name = $name; 65 66 return $this; 67 } 68 69 /** 70 * Get name 71 * 72 * @return string 73 */ 74 public function getName() 75 { 76 return $this->name; 77 } 78 79 /** 80 * Set price 81 * 82 * @param integer $price 83 * @return Product 84 */ 85 public function setPrice($price) 86 { 87 $this->price = $price; 88 89 return $this; 90 } 91 92 /** 93 * Get price 94 * 95 * @return integer 96 */ 97 public function getPrice() 98 { 99 return $this->price; 100 } 101 102 /** 103 * Set description 104 * 105 * @param string $description 106 * @return Product 107 */ 108 public function setDescription($description) 109 { 110 $this->description = $description; 111 112 return $this; 113 } 114 115 /** 116 * Get description 117 * 118 * @return string 119 */ 120 public function getDescription() 121 { 122 return $this->description; 123 } 124 }
生成したエンティティをDBに反映する
Productエンティティ
を作成しましたが、それに対応するproductテーブル
はまだDBに存在していません。
Productエンティティ
に対応するproductテーブル
を作成する必要があります。
既に作成されているエンティティを元にして、DBのスキーマを更新するというdoctrine:schema:update
コマンドがあります。
これを実行して、Productエンティティ
に対応するproductテーブル
を生成します。
app/console doctrine:schema:update ATTENTION: This operation should not be executed in a production environment. Use the incremental update to detect changes during development and use the SQL DDL provided to manually update your database in production. The Schema-Tool would execute "1" queries to update the database. Please run the operation by passing one - or both - of the following options: doctrine:schema:update --force to execute the command doctrine:schema:update --dump-sql to dump the SQL statements to the screen
doctrine:schema:update --dump-sql
を実行すると、実際に実行されるSQLを確認することができます。
doctrine:schema:update --force
を実行すると、--dump-sql
で確認したSQLが実行されます。
実際にやっていきます。
try-doctrine
に存在するテーブルを確認します。
まだ何も作成していないので、Emptyになっています。
mysql> show tables; Empty set (0.00 sec)
doctrine:schema:update --dump-sql
を実行します。
先程生成したエンティティと同等の内容のテーブルを生成するSQLが発行されています。
doctrine:schema:update --force
を実行すると、このSQLが実行されることになります。
$ app/console doctrine:schema:update --dump-sql CREATE TABLE product (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, price INT NOT NULL, description LONGTEXT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
実際に実行されるSQLを確認したところで、doctrine:schema:update --force
を実行して、テーブルを作成します。
app/console doctrine:schema:update --force Updating database schema... Database schema updated successfully! "1" queries were executed
try-doctrine
に存在するテーブルを確認します。
productテーブル
が新規に作成され、フィールド名等の設定もエンティティの設定と同等なものになっています。
mysql> show tables; +------------------------+ | Tables_in_try-doctrine | +------------------------+ | product | +------------------------+ 1 row in set (0.00 sec) mysql> show columns from product; +-------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(255) | NO | | NULL | | | price | int(11) | NO | | NULL | | | description | longtext | NO | | NULL | | +-------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
これで、PHPでDoctrineを介してProductエンティティ
を操作することで、DBを操作する準備が整いました。
おわりに
今回は DoctrineとDBを連携するための設定
エンティティの作成
エンティティを元したテーブル作成
を紹介しました。
次回は、DoctrineでCRUDをする具体例を紹介したいと思います。
また、この記事は、@mrtryの勉強の一環で書いていますので、
お気づきの点などがありましたら、コメント等でご指摘いただければ幸いです!