[CakePHP] Transactionを使う方法とEntityクラスを利用してInsert、Update、Deleteする方法
こんにちは。明月です。
この投稿はPHPのCakeフレームワークでTransactionを使う方法とEntityクラスを利用してInsert、Update、Deleteする方法に関する説明です。
以前、CakePHPのフレームワークを利用せずに、データベースにInsertやUpdate、Deleteに関して説明したことがあります。
link - [CakePHP] データベース(MariaDB(Mysql))を接続する方法
でも、我々はデータ無欠性のため、トランザクションを使うし、Fetch機能でオブジェクト単位でデータを追加する方法で実装しなければならないです。
テーブルの例は以前の投稿を続けて利用します。
link - [CakePHP] ORMのテーブルFetch設定
Userテーブルでデータを入力する後、派生テーブルのInfoテーブルのデータを入力します。そしてInfo2テーブルのデータを入力することで考えましょう。
UserテーブルのキーとInfoテーブルの外部キーが自動生成するタイプじゃなく、nvarcharタイプのユーザかUserテーブルのキーとInfoテーブルの外部キーが自動生成するタイプじゃなく、nvarcharタイプのユーザから取得するデータなのでUserテーブルをInsertした後InfoテーブルをInsertすることの順番で問題ありません。
でも、Info2のテーブルの場合はInfoテーブルのキーで外部キーが結んでいますが、この場合は自動生成タイプなのでInfoテーブルがinsertした後、キーを検索してInfo2テーブルに入力しなければならないです。
この順番のテーブル入力する作業が多いと思えば、ソースがすごく複雑になるでしょう。
また、データベース処理する中でエラーが発生する時、全てをロールバックしなければならないですが、それ時にトランザクション(transaction)を利用すればできるでしょう。
<?php
namespace App\Controller;
use Cake\Datasource\ConnectionManager;
use Cake\ORM\TableRegistry;
use Cake\Core\Exception\Exception;
class HomeController extends AppController {
public function index() {
// connectionマネージャーからconnectionを取得する。
$connection = ConnectionManager::get('default');
// トランザクション処理
$connection->transactional(function ($conn) {
// トランザクション中でエラーがなければcommitになるし、エラーが発生する時にrollbackになる。
});
}
}
CakePHPフレームワークではトランザクションがオブザーバーパターンにもう実装されています。JavaやC#はパターンを実装しましたが。。
トランザクションを利用してデータを入力しましょう。
<?php
namespace App\Controller;
use Cake\Datasource\ConnectionManager;
use Cake\ORM\TableRegistry;
class HomeController extends AppController {
public function index() {
// connectionマネージャーからconnectionを取得する。
$connection = ConnectionManager::get('default');
//トランザクション
$connection->transactional(function ($conn) {
// Userテーブルのレジストリを取得
$userTable = TableRegistry::get('User');
// Entityを生成する。
$user = $userTable->newEntity();
// idカラムに「new」を入力してnameカラムに「new Name」を入力する。
$user->id = "new";
$user->name = "new Name";
// 格納(transactionの中でエラーが発生しなければ、格納される。)
$userTable->save($user);
// Infoテーブルのレジストリを取得
$infoTable = TableRegistry::get('Info');
// Entityを生成する。
$info = $infoTable->newEntity();
// Userクラスからidを取得してInfoクラスに外部キーを設定する。
$info->id = $user->id;
$info->age = 10;
// 格納(transactionの中でエラーが発生しなければ、格納される。)
$infoTable->save($info);
// Info2テーブルのレジストリを取得
$info2Table = TableRegistry::get('Info2');
// Entityを生成する。
$info2 = $info2Table->newEntity();
// Infoクラスのidxを取得してInfo2クラスの外部キーに設定する。
$info2->info_idx = $info->idx;
$info2->birth = 10;
// 格納(transactionの中でエラーが発生しなければ、格納される。)
$info2Table->save($info2);
});
}
}
上の例でInfoテーブルの場合は外部キー(id)に入力するデータにはEntityデータの「id」で設定するので別にデータベースから受取るのはありませんが、Info2テーブルの場合はInfoテーブルの外部キーが自動生成のキーなのでInfoデータがinsertした後のデータをデータベースから受け取らければならないです。
実際にtransation中で「$info->idx」キーがありませんが、「$info2->info = $info->idx」を設定することで、連携することが出来ます。
今回はUpdateとDeleteです。
UpdateとDeleteはデータベースからデータを修正や削除することで一応検索してデータを取得します。
<?php
namespace App\Controller;
use Cake\Datasource\ConnectionManager;
use Cake\ORM\TableRegistry;
class HomeController extends AppController {
public function index() {
// connectionマネージャーからconnectionを取得する。
$connection = ConnectionManager::get('default');
// トランザクション
$connection->transactional(function ($conn) {
// Userテーブルのレジストリを取得
$table = TableRegistry::get('User');
// Query式を取得
$query = $table->find();
// idが「new」のデータを検索する。
$query = $query->where(['id' => 'new']);
// データを取得する。
$user = $query->first();
// nameを修正する。
$user->name = "modified!!";
// 格納(transactionの中でエラーが発生しなければ、格納される。)
$table->save($user);
});
}
}
上のデータを取得してEntityインスタンスのnameのデータを修正してsave関数を呼出したらデータベースに格納されています。
<?php
namespace App\Controller;
use Cake\Datasource\ConnectionManager;
use Cake\ORM\TableRegistry;
use Cake\Core\Exception\Exception;
class HomeController extends AppController {
public function index() {
// connectionマネージャーからconnectionを取得する。
$connection = ConnectionManager::get('default');
// トランザクション
$connection->transactional(function ($conn) {
// Userテーブルのレジストリを取得
$table = TableRegistry::get('User');
// Query式を取得
$query = $table->find();
// idが「new」のデータを検索する。
$query = $query->where(['id' => 'new']);
// データを取得
$user = $query->first();
// 派生データを全て削除する。
// Infoテーブルを繰り返す。
foreach($user->infos as $info) {
// Info2テーブルを繰り返す。
foreach($info->info2s as $info2) {
// Info2テーブルのデータを削除(transactionの中でエラーが発生しなければ、格納される。)
TableRegistry::get('Info2')->delete($info2);
}
// Infoテーブルのデータを削除(transactionの中でエラーが発生しなければ、格納される。)
TableRegistry::get('Info')->delete($info);
}
// Userテーブルデータを削除(transactionの中でエラーが発生しなければ、格納される。)
$table->delete($user);
});
}
}
削除されたことを確認できました。
ここまでPHPのCakeフレームワークでTransactionを使う方法とEntityクラスを利用してInsert、Update、Deleteする方法に関する説明でした。
ご不明なところや間違いところがあればコメントしてください。
- [CakePHP] Errorページを設定する方法2020/02/20 03:00:00
- [CakePHP] Transactionを使う方法とEntityクラスを利用してInsert、Update、Deleteする方法2020/02/19 03:00:00
- [CakePHP] ORMのテーブルFetch設定2020/02/18 03:00:00
- [CakePHP] Cakeフレームワークでデータベースに接続する時に使うQuery式とEntityクラス、Tableクラス、ResultSet2020/02/17 08:16:23
- [CakePHP] データベース(MariaDB(Mysql))を接続する方法2020/02/14 03:00:00
- [PHP] namespaceとuse2020/02/13 03:00:00
- [CakePHP] RequestとResponseに関して2020/02/12 03:00:02
- [CakePHP] PHPのCakeからAjax要請がある時、jsonタイプ(json_encode関数)でResponseする方法とControllerでViewを選択する方法2020/02/08 03:00:00
- [CakePHP] MVCフレームワークのCakeをインストールする方法2020/02/07 03:00:02
- check2024/04/10 19:03:53
- [Java] 64.Spring bootとReactを連結する方法(Buildする方法)2022/03/25 21:02:18
- [Javascript] Node.jsをインストールしてReactを使う方法2022/03/23 18:01:34
- [Java] 63. Spring bootでcronスケジューラとComponentアノテーション2022/03/16 18:57:30
- [Java] 62. Spring bootでWeb-Filterを設定する方法(Spring Security)2022/03/15 22:16:37
- [Java] JWT(Json Web Token)を発行、確認する方法2022/03/14 19:12:58
- [Java] 61. Spring bootでRedisデータベースを利用してセッションクラスタリング設定する方法2022/03/01 18:20:52
- [Java] 60. Spring bootでApacheの連結とロードバランシングを設定する方法2022/02/28 18:45:48
- [Java] 59. Spring bootのJPAでEntityManagerを使い方2022/02/25 18:27:48
- [Java] 58. EclipseでSpring bootのJPAを設定する方法2022/02/23 18:11:10
- [Java] 57. EclipseでSpring bootを設定する方法2022/02/22 19:04:49
- [Python] Redisデータベースに接続して使い方2022/02/21 18:23:49
- [Java] Redisデータベースを接続して使い方(Jedisライブラリ)2022/02/16 18:13:17
- [C#] Redisのデータベースを接続して使い方2022/02/15 18:46:09
- [CentOS] Redisデータベースをインストールする方法とコマンドを使い方2022/02/14 18:33:07