本記事では、CakePHP3で複数データベースを利用したアクセス方法を解説しています。
マスタ系、トランザクション系などのデータベースを分離して、
負荷分散などをする場合に活用できると思います。
app.phpの修正
最初に、デフォルト以外のデータベースの設定を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
'tools_db' => [ 'className' => Connection::class, 'driver' => Mysql::class, 'persistent' => false, 'host' => 'hogehoge', /* * CakePHP will use the default DB port based on the driver selected * MySQL on MAMP uses port 8889, MAMP users will want to uncomment * the following line and set the port accordingly */ 'username' => 'username', 'password' => 'hogehoge', 'database' => 'tools_db', /* * You do not need to set this flag to use full utf-8 encoding (internal default since CakePHP 3.6). */ 'timezone' => '+09:00', 'flags' => [], 'cacheMetadata' => true, 'log' => false, /** * Set identifier quoting to true if you are using reserved words or * special characters in your table or column names. Enabling this * setting will result in queries built using the Query Builder having * identifiers quoted when creating SQL. It should be noted that this * decreases performance because each query needs to be traversed and * manipulated before being executed. */ 'quoteIdentifiers' => false, /** * During development, if using MySQL < 5.6, uncommenting the * following line could boost the speed at which schema metadata is * fetched from the database. It can also be set directly with the * mysql configuration directive 'innodb_stats_on_metadata = 0' * which is the recommended value in production environments */ 'url' => env('DATABASE_URL', null), ], |
モデルを直接修正する場合
Users
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
<?php namespace App\Model\Table; use Cake\ORM\Query; use Cake\ORM\RulesChecker; use Cake\ORM\Table; use Cake\Validation\Validator; /** * Users Model * * @property \App\Model\Table\RolesTable&\Cake\ORM\Association\BelongsTo $Roles * @property \App\Model\Table\UserStatusKindsTable&\Cake\ORM\Association\BelongsTo $UserStatusKinds * @property \App\Model\Table\BookmarksTable&\Cake\ORM\Association\HasMany $Bookmarks * @property \App\Model\Table\NotesTable&\Cake\ORM\Association\HasMany $Notes * * @method \App\Model\Entity\User get($primaryKey, $options = []) * @method \App\Model\Entity\User newEntity($data = null, array $options = []) * @method \App\Model\Entity\User[] newEntities(array $data, array $options = []) * @method \App\Model\Entity\User|false save(\Cake\Datasource\EntityInterface $entity, $options = []) * @method \App\Model\Entity\User saveOrFail(\Cake\Datasource\EntityInterface $entity, $options = []) * @method \App\Model\Entity\User patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = []) * @method \App\Model\Entity\User[] patchEntities($entities, array $data, array $options = []) * @method \App\Model\Entity\User findOrCreate($search, callable $callback = null, $options = []) * * @mixin \Cake\ORM\Behavior\TimestampBehavior */ class UsersTable extends Table { /** * Initialize method * * @param array $config The configuration for the Table. * @return void */ public function initialize(array $config) { parent::initialize($config); $this->setTable('users'); $this->setDisplayField('name'); $this->setPrimaryKey('id'); $this->addBehavior('Timestamp'); $this->belongsTo('Roles', [ 'foreignKey' => 'role_id', 'joinType' => 'INNER' ]); $this->belongsTo('UserStatusKinds', [ 'foreignKey' => 'user_status_kind_id', 'joinType' => 'INNER' ]); $this->hasMany('Bookmarks', [ 'foreignKey' => 'user_id' ]); $this->hasMany('Notes', [ 'foreignKey' => 'user_id' ]); } /** * Default validation rules. * * @param \Cake\Validation\Validator $validator Validator instance. * @return \Cake\Validation\Validator */ public function validationDefault(Validator $validator) { $validator ->integer('id') ->allowEmptyString('id', null, 'create'); $validator ->scalar('name') ->maxLength('name', 128) ->requirePresence('name', 'create') ->notEmptyString('name'); $validator ->scalar('kana') ->maxLength('kana', 128) ->requirePresence('kana', 'create') ->notEmptyString('kana'); $validator ->boolean('gender') ->allowEmptyString('gender'); $validator ->date('birthday') ->allowEmptyDate('birthday'); $validator ->email('email') ->requirePresence('email', 'create') ->notEmptyString('email'); $validator ->scalar('password') ->maxLength('password', 255) ->requirePresence('password', 'create') ->notEmptyString('password'); $validator ->scalar('hash_key') ->maxLength('hash_key', 255) ->allowEmptyString('hash_key'); $validator ->dateTime('logined_at') ->allowEmptyDateTime('logined_at'); return $validator; } /** * Returns a rules checker object that will be used for validating * application integrity. * * @param \Cake\ORM\RulesChecker $rules The rules object to be modified. * @return \Cake\ORM\RulesChecker */ public function buildRules(RulesChecker $rules) { $rules->add($rules->isUnique(['email'])); $rules->add($rules->existsIn(['role_id'], 'Roles')); $rules->add($rules->existsIn(['user_status_kind_id'], 'UserStatusKinds')); return $rules; } } |
Tableクラスに、下記の行を追加することで、デフォルト以外のデータベースにアクセスできます。
1 2 3 4 5 6 7 8 9 |
/** * Returns the database connection name to use by default. * * @return string */ public static function defaultConnectionName() { return 'second_db'; } |
bakeを利用してモデルを作成する場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
[hogehoge@svxxx src]$ ../bin/cake bake model --connection second_db users PHP Notice: date_default_timezone_set(): Timezone ID '+09:00' is invalid in /home/hogehoge/test/public_html/xxx/config/bootstrap.php on line 101 Notice: date_default_timezone_set(): Timezone ID '+09:00' is invalid in /home/hogehoge/test/public_html/xxx/config/bootstrap.php on line 101 One moment while associations are detected. Baking table class for Users... Creating file /home/hogehoge/test/public_html/xxx/src/Model/Table/UsersTable.php Wrote `/home/hogehoge/test/public_html/xxx/src/Model/Table/UsersTable.php` Baking entity class for Users... Creating file /home/hogehoge/test/public_html/xxx/src/Model/Entity/Users.php Wrote `/home/hogehoge/test/public_html/xxx/src/Model/Entity/Users.php` Baking test fixture for Users... Creating file /home/hogehoge/test/public_html/xxx/tests/Fixture/UsersFixture.php Wrote `/home/hogehoge/test/public_html/xxx/tests/Fixture/UsersFixture.php` Bake is detecting possible fixtures... Baking test case for App\Model\Table\UsersTable ... Creating file /home/hogehoge/test/public_html/xxx/tests/TestCase/Model/Table/UsersTableTest.php Wrote `/home/hogehoge/test/public_html/xxx/tests/TestCase/Model/Table/UsersTableTest.php` [hogehoge@xxx src]$ |
bakeを利用して、モデルを変更する方が、簡単な上に、修正ミスがないので、
なるべく、bakeを利用して対応した方が良いと思います。