| 86 | | ++ Starting new project |
| 87 | | ++ Working with existing databases |
| 88 | | ++ Creating tables |
| | 86 | ++ 新しいプロジェクトを始める |
| | 87 | |
| | 88 | Doctrine_RecordはすべてのDoctrineを使ったプロジェクトの基本コンポーネントになります。少なくともそれぞれのデータベーステーブルに対してDoctrine_Recordが一つあります。Doctrine_Record は [http://www.martinfowler.com/eaaCatalog/activeRecord.html Active Record pattern] のパターンを継承しています。 |
| | 89 | |
| | 90 | Doctrineは常に主キーを持たないテーブルに対して'id'という名前の主キーを追加します。Doctrine_Record を継承してsetTableDefinitionメソッドをhasColumn()で定義してそれらのクラスをエクスポートするだけでデータベースのテーブルが作成されます。 |
| | 91 | |
| | 92 | 'user'というデータベーステーブルを作成することを考えてみます。カラムはid(primary key)、name、username、passwordとcreatedです。Doctrineが既にインストールされているとして、必要なものは下記の数行です: |
| | 93 | |
| | 94 | User.php : |
| | 95 | <code type="php"> |
| | 96 | class User extends Doctrine_Record |
| | 97 | { |
| | 98 | public function setTableDefinition() |
| | 99 | { |
| | 100 | // set 'user' table columns, note that |
| | 101 | // id column is auto-created as no primary key is specified |
| | 102 | |
| | 103 | $this->hasColumn('name', 'string',30); |
| | 104 | $this->hasColumn('username', 'string',20); |
| | 105 | $this->hasColumn('password', 'string',16); |
| | 106 | } |
| | 107 | |
| | 108 | public function setUp() |
| | 109 | { |
| | 110 | $this->actAs('Timestampable'); |
| | 111 | } |
| | 112 | } |
| | 113 | </code> |
| | 114 | |
| | 115 | この代わりにYAMLスキーマを使ってDoctrineのスキーマ情報を指定することも可能です。以下がDoctrine_Recordから生成するためのuser.ymlの例です |
| | 116 | |
| | 117 | <code type="yml"> |
| | 118 | --- |
| | 119 | User: |
| | 120 | actAs: [Timestampable] |
| | 121 | columns: |
| | 122 | name: string(30) |
| | 123 | username: string(20) |
| | 124 | password: string(16) |
| | 125 | </code> |
| | 126 | |
| | 127 | 以下のコマンドを走らせてyamlからphpこーどを生成することができます |
| | 128 | |
| | 129 | <code type="php"> |
| | 130 | Doctrine::generateModelsFromYaml('/path/to/user.yml', '/path/to/generate/models); |
| | 131 | </code> |
| | 132 | |
| | 133 | パス /path/to/generate/models/ か /path/to/generate/models/generated を見てください。ここにUser.phpとBaseUser.phpがあるはずです。User.phpにこーどを追加することで任意の機能を追加することができます。まだBaseUser.phpにはYAMLスキーマファイルから毎回生成されます。 |
| | 134 | |
| | 135 | これでDoctrine_Recordクラスが使えるようになりました、ここからデータベースにエクスポートしたり、テーブルを作成したりできます。上のUserクラスをデータベースにエクスポートするために次のシンプルなビルドスクリプトを使います: |
| | 136 | |
| | 137 | <code type="php"> |
| | 138 | //Doctrineのベースクラスを読み込む |
| | 139 | require_once('path-to-doctrine/lib/Doctrine.php'); |
| | 140 | |
| | 141 | //autoloaderの登録 |
| | 142 | spl_autoload_register(array('Doctrine', 'autoload')); |
| | 143 | |
| | 144 | require_once('User.php'); |
| | 145 | |
| | 146 | //接続のセットアップ |
| | 147 | Doctrine_Manager::connection('mysql://user:pass@localhost/test'); |
| | 148 | |
| | 149 | //クラスのエクスポート |
| | 150 | Doctrine::createTablesFromArray(array('User')); |
| | 151 | </code> |
| | 152 | |
| | 153 | これで基本的なCRUDオペレーションをサポートするUserモデルが使えるようになりました! |
| | 154 | |
| | 155 | ++ 既存のデータベースと連携する |
| | 156 | |
| | 157 | +++ はじめに |
| | 158 | |
| | 159 | DoctrineのようなORMツールを使ってよく起こることはデータベースとコードが肥大/複雑になることです。SQLを直書きするより、よいツールが必要です。 |
| | 160 | |
| | 161 | Doctrineは既存のデータベースからDoctrine_Recordクラスの生成をサポートします。ドメインモデルに対してすべてのDoctrine_Recordクラスを一から書く必要はありません。 |
| | 162 | |
| | 163 | +++ 最初のインポートを作成する |
| | 164 | |
| | 165 | 'file'という名前の一つのテーブルを持つtestというMySQLのデータベースを考えてみましょう。 |
| | 166 | |
| | 167 | fileテーブルは次のSQL命令文で作成されました: |
| | 168 | |
| | 169 | <code type="sql"> |
| | 170 | CREATE TABLE file ( |
| | 171 | id INT UNSIGNED AUTO_INCREMENT NOT NULL, |
| | 172 | name VARCHAR(150), |
| | 173 | size BIGINT, |
| | 174 | modified BIGINT, |
| | 175 | type VARCHAR(10), |
| | 176 | content TEXT, |
| | 177 | path TEXT, |
| | 178 | PRIMARY KEY(id)) |
| | 179 | </code> |
| | 180 | |
| | 181 | これをDoctrine_Recordクラスに変換することを考えます。これは次のコードを使って簡単にできます: |
| | 182 | |
| | 183 | <code type="php"> |
| | 184 | require_once('path-to-doctrine/lib/Doctrine.php'); |
| | 185 | |
| | 186 | spl_autoload_register(array('Doctrine', 'autoload')); |
| | 187 | Doctrine_Manager::connection('mysql://root:dc34@localhost/test'); |
| | 188 | |
| | 189 | // インポートメソッドはインポートディレクトの入ったパラメータを1つとります。 |
| | 190 | //インポートディレクトリには生成されたファイルが保存されます。 |
| | 191 | Doctrine::generateModelsFromDb('myrecords'); |
| | 192 | </code> |
| | 193 | |
| | 194 | |
| | 195 | これでおしまいです!myrecords/generatedディレクトリ以下にでFile.phpという名前のファイルが保存されました。ファイルの内容は以下の通りです: |
| | 196 | |
| | 197 | <code type="php"> |
| | 198 | /** |
| | 199 | * This class has been auto-generated by the Doctrine ORM Framework |
| | 200 | */ |
| | 201 | abstract class BaseFile extends Doctrine_Record |
| | 202 | { |
| | 203 | |
| | 204 | public function setTableDefinition() |
| | 205 | { |
| | 206 | $this->setTableName('file'); |
| | 207 | $this->hasColumn('id', 'integer', 4, array('unsigned' => 1, 'values' => array(), 'primary' => true, 'notnull' => true, 'autoincrement' => true)); |
| | 208 | $this->hasColumn('name', 'string', 150, array('fixed' => false, 'values' => array(), 'primary' => false, 'notnull' => false, 'autoincrement' => false)); |
| | 209 | $this->hasColumn('size', 'integer', 8, array('unsigned' => 0, 'values' => array(), 'primary' => false, 'notnull' => false, 'autoincrement' => false)); |
| | 210 | $this->hasColumn('modified', 'integer', 8, array('unsigned' => 0, 'values' => array(), 'primary' => false, 'notnull' => false, 'autoincrement' => false)); |
| | 211 | $this->hasColumn('type', 'string', 10, array('fixed' => false, 'values' => array(), 'primary' => false, 'notnull' => false, 'autoincrement' => false)); |
| | 212 | $this->hasColumn('content', 'string', null, array('fixed' => false, 'values' => array(), 'primary' => false, 'notnull' => false, 'autoincrement' => false)); |
| | 213 | $this->hasColumn('path', 'string', null, array('fixed' => false, 'values' => array(), 'primary' => false, 'notnull' => false, 'autoincrement' => false)); |
| | 214 | } |
| | 215 | |
| | 216 | public function setUp() |
| | 217 | { |
| | 218 | parent::setUp(); |
| | 219 | } |
| | 220 | |
| | 221 | } |
| | 222 | </code> |
| | 223 | |
| | 224 | またFile.phpというファイルがmyrecordsディレクトリ内に保存されています。ファイルの内容は以下の通り: |
| | 225 | |
| | 226 | |
| | 227 | <code type="php"> |
| | 228 | /** |
| | 229 | * This class has been auto-generated by the Doctrine ORM Framework |
| | 230 | */ |
| | 231 | class FileTable extends Doctrine_Table |
| | 232 | { |
| | 233 | |
| | 234 | |
| | 235 | |
| | 236 | } |
| | 237 | </code> |
| | 238 | |
| | 239 | ここにカスタムメソッドを追加してDoctrine::getTable('User')を使って呼ぶことができます。 |
| | 240 | |
| | 241 | +++ Singularizing Import |
| | 242 | |
| | 243 | デフォルトではDoctrineは既存のデータベースから読み込まれた各モデルの名前を単数型にしようとします。この機能を望まない方は以下の方法で簡単にoffにしてください |
| | 244 | |
| | 245 | <code type="php"> |
| | 246 | Doctrine_Manager::getInstance()->setAttribute('singularize_import', false); |
| | 247 | </code> |
| | 248 | |
| | 249 | これで"files"というテーブル名からは"File.php"というモデルは無く、"Files.php"というモデルが生成されます。 |
| | 250 | |
| | 251 | ++ テーブルの作成 |
| | 252 | |
| | 253 | +++ はじめに |
| | 254 | |
| | 255 | Doctrineはレコードクラスをデータベースにエクスポートすることをサポートします。レコードクラスにある定義からDoctrineがデータベース内にテーブルを作ります。 |
| | 256 | |
| | 257 | 次の定義を持つUserとPhonenumberという名前のクラスを考えます: |
| | 258 | |
| | 259 | <code type="php"> |
| | 260 | // file User.php |
| | 261 | class User extends Doctrine_Record |
| | 262 | { |
| | 263 | public function setTableDefinition() |
| | 264 | { |
| | 265 | $this->hasColumn('name', 'string', 20); |
| | 266 | } |
| | 267 | public function setUp() |
| | 268 | { |
| | 269 | $this->hasMany('Phonenumber', array('local' => 'id', |
| | 270 | 'foreign' => 'user_id')); |
| | 271 | } |
| | 272 | } |
| | 273 | // file Phonenumber.php |
| | 274 | class Phonenumber extends Doctrine_Record |
| | 275 | { |
| | 276 | public function setTableDefinition() |
| | 277 | { |
| | 278 | $this->hasColumn('phonenumber', 'string', 20); |
| | 279 | $this->hasColumn('user_id', 'integer'); |
| | 280 | } |
| | 281 | public function setUp() |
| | 282 | { |
| | 283 | $this->hasOne('User', array('local' => 'user_id', |
| | 284 | 'foreign' => 'id', |
| | 285 | 'onDelete' => 'CASCADE')); |
| | 286 | } |
| | 287 | } |
| | 288 | </code> |
| | 289 | |
| | 290 | これらのクラスは'models/'ディレクトリにあるとします。このディレクトリの中をDoctrineに回遊させて、以下のスクリプトを使って各クラスをデータベース構造に追加します: |
| | 291 | |
| | 292 | <code type="php"> |
| | 293 | |
| | 294 | require_once('path-to-doctrine/lib/Doctrine.php'); |
| | 295 | |
| | 296 | spl_autoload_register(array('Doctrine', 'autoload')); |
| | 297 | |
| | 298 | //エクスポートするためにデータベース接続が必要 |
| | 299 | Doctrine_Manager::connection('mysql://user:pass@localhost/test'); |
| | 300 | |
| | 301 | Doctrine::createTablesFromModels('models'); |
| | 302 | </code> |
| | 303 | |
| | 304 | これはMySQL上で次のクエリーを実行します。 |
| | 305 | |
| | 306 | <code type="sql"> |
| | 307 | CREATE TABLE user (id BIGINT AUTO_INCREMENT, name VARCHAR(20), PRIMARY KEY(id), INDEX(id)); |
| | 308 | CREATE TABLE phonenumber (id INT AUTO_INCREMENT, phonenumber VARCHAR(20), user_id BIGINT, PRIMARY KEY(id), INDEX(user_id)); |
| | 309 | ALTER TABLE phonenumber ADD CONSTRAINT FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE CASCADE; |
| | 310 | </code> |
| | 311 | |
| | 312 | 以下の点に注意してください: |
| | 313 | |
| | 314 | # 主キーカラムを指定していないのでオートインクリメントの主キーが自動追加されます |
| | 315 | # Doctrineはインデックスを参照された関連カラムに自動追加します(これはMySQLが必要とします) |
| | 316 | |
| | 317 | +++ エクスポートクエリーを手に入れる |
| | 318 | |
| | 319 | エクスポートクエリーをすぐに実行するのではなく、クエリーの文字列を入手してそれらをbuild.sqlファイルに保存したい状況があるとします。これは次のように達成できます: |
| | 320 | |
| | 321 | <code type="php"> |
| | 322 | require_once('path-to-doctrine/lib/Doctrine.php'); |
| | 323 | |
| | 324 | spl_autoload_register(array('Doctrine', 'autoload')); |
| | 325 | |
| | 326 | Doctrine_Manager::connection('mgsql://user:pass@localhost/test'); |
| | 327 | |
| | 328 | $queries = Doctrine::generateSqlFromModels('models'); |
| | 329 | |
| | 330 | echo $queries; |
| | 331 | </code> |
| | 332 | |
| | 333 | 同じ様にエクスポートを実行するために必要なSQLクエリーの文字を取得したい場合は Doctrine::generateSqlFromModels() を使います。 |
| | 334 | |
| | 335 | +++ エクスポートオプション |
| | 336 | |
| | 337 | <code type="php"> |
| | 338 | // テーブル定義と制約などのすべてをエクスポートする |
| | 339 | $manager = Doctrine_Manager::getInstance(); |
| | 340 | |
| | 341 | $manager->setAttribute(Doctrine::ATTR_EXPORT, Doctrine::EXPORT_ALL); |
| | 342 | |
| | 343 | // 制約無しでクラスをエクスポートする |
| | 344 | |
| | 345 | $manager->setAttribute(Doctrine::ATTR_EXPORT, Doctrine::EXPORT_TABLES ^ |
| | 346 | Doctrine::EXPORT_CONSTRAINTS); |
| | 347 | |
| | 348 | //エクスポートをoffにする |
| | 349 | |
| | 350 | $manager->setAttribute(Doctrine::ATTR_EXPORT, Doctrine::EXPORT_NONE); |
| | 351 | |
| | 352 | $sql = Doctrine::generateSqlFromModels(); |
| | 353 | </code> |
| | 354 | |