業務オブジェクトを表現する。
業務オブジェクト とは : 業務ロジックの中である程度のまとまりを持つ「機能の単位」 (としておく...)
以下のものを使用して作成する。
Connection | データを保存|読み込みするための接続先。トランザクション管理も行う |
DataSource | 特定のデータ構造に対する処理を行うデータソース |
Criteria | DataSourceに選択条件を与える、またはCommand作成時の選択条件を作成する |
Command | Connectionに対して直接操作を行うためのCommand |
データベースなどに接続してデータの保存、読み出しを行う。定義は抽象化されていて、データベースの実体で共通化した操作のみを公開する。
Connectionの実体(インスタンス)は直接生成せず、ConnectionFactory#getConnection()を使用して取得する。
connect | 接続を開く |
disconnect | 接続を閉じる |
beginTransaction | トランザクションを開始する |
commitTransaction | トランザクションを確定する |
rollbackTransaction | トランザクションを破棄する |
query | 選択クエリーを実行する。 |
queryBatch | 複数の選択クエリーを実行する。 |
update | 更新クエリーを実行する。 |
updateBatch | 複数の更新クエリーを実行する。 |
quote | 接続先データベースに応じた文字列引用処理(シングルクォーテーションを二重化する、など) |
systemDate | 接続先データベースの現在時刻を取得する |
describeTable | テーブル情報をEntityPropertyクラスとして取得する。 |
describeStoredProcedure | ストアドプロシージャをEntityPropertyクラスとして取得する。 |
接続先の設定に名前をつけ、その名前を指定することで接続先を決定する。>>設定
デフォルトの接続先を使う
//接続取得
$connection = CFW_Data_ConnectionFactory::getConnection(array("default"));
//以下、$connection を使った処理...
system,functionごとに接続先を定義している場合
//接続取得
$connection = CFW_Data_ConnectionFactory::getConnection(array("system","funciton"));
//以下、$connection を使った処理...
1.Commandオブジェクトを作成しCommandを実行する
//接続取得
$connection = CFW_Data_ConnectionFactory::getConnection(array("system","funciton"));
try{
$connection->connect();
//コマンド準備
$command = new CFW_Data_Command("select * from users");
$command->setConnection($connection);
//実行して結果を得る
$result = $command->executeQuery();
}
catch(Exception $ex){
$logger->error(__METHOD__,$ex->getMessage());
$logger->error(__METHOD__,$ex->getStack());
}
//後始末
$connection->disconect();
2.またはあらかじめ作成した複数のCommandオブジェクトを実行する
//接続取得
$connection = CFW_Data_ConnectionFactory::getConnection(array("system","funciton"));
try{
$connection->connect();
//コマンド準備
$command1 = new CFW_Data_Command("select * from users where user_id = ?");
$command1->addParameter(new CFW_Data_Parameter(":user_id",1);
$command2 = new CFW_Data_Command("select * from auth_users_roles where user_id = ?");
$command2->addParameter(new CFW_Data_Parameter(":user_id",1);
//実行して結果を得る
$result = $connection->queryBatch(array($command1,$command2));
}
catch(Exception $ex){
$logger->error(__METHOD__,$ex->getMessage());
$logger->error(__METHOD__,$ex->getStack());
}
//後始末
$connection->disconect();
beginTransaction(),commitTransaction(),rollbackTransaction()を使用する
//接続取得
$connection = CFW_Data_ConnectionFactory::getConnection(array("system","funciton"));
try{
$connection->connect();
//トランザクション開始
$connection->begeinTransaction();
//コマンド準備
$command1 = new CFW_Data_Command("insert into users values(?,?)");
$command1->addParameter(new CFW_Data_Parameter(":user_id",1);
$command1->addParameter(new CFW_Data_Parameter(":user_name","sample user");
//コマンド実行先設定
$command->setConnection($connection);
//実行して結果を得る
$result = $command1->executeUpdate();
//トランザクション確定
$connection->commitTransaction();
}
catch(Exception $ex){
//トランザクション破棄
$connection->rollbackTransaction();
$logger->error(__METHOD__,$ex->getMessage());
$logger->error(__METHOD__,$ex->getStack());
}
//後始末
$connection->disconect();
接続先データベースごとに異なる実装クラスが存在する。
Connectionのデータに対する操作を行う。
setConnection | 既に開かれている接続を設定する |
addParamter | パラメータを追加する |
executeQuery | 選択クエリーを実行する |
executeUpdate | 更新クエリーを実行する |
executeQueryAsObject | 選択クエリーを実行し、指定したクラスのインスタンスのリストを作成する。 |
クエリーテキストとパラメータからCommnadオブジェクトを作成し、executeQuery()を実行する。
//接続取得
$connection = CFW_Data_ConnectionFactory::getConnection(array("system","funciton"));
try{
$connection->connect();
//コマンド準備
$command1 = new CFW_Data_Command("select * from users where user_id = ?");
$command1->addParameter(new CFW_Data_Parameter(":user_id",1);
//接続先を設定する
$command->setConnection($connection);
//実行して結果を得る
$result = $command->executeQuery());
}
catch(Exception $ex){
$logger->error(__METHOD__,$ex->getMessage());
$logger->error(__METHOD__,$ex->getStack());
}
//後始末
$connection->disconect();
特定のデータ構造のデータに対する操作を行う。データ構造はEntityPropertyに設定する。
connect | 接続先への接続を開く |
disconnect | 接続先への接続を閉じる |
setConnection | 既に開かれている接続を設定する |
setProperty | EntityProperty(データ構造)を設定する |
save | 渡されたエンティティの状態(isNew,isModified,isDeleted)に基づき追加、更新、削除を実行する |
update | 指定選択条件の行を指定データで更新する。 |
insert | 指定データを追加。 |
delete | 指定選択条件の行を削除する。 |
find | 指定選択条件の行を取得する。 |
findByPk | 主キーを指定して行を取得する。 |
save()を呼び出した時エンティティがisNew 且つ isModified の場合データを追加する。
//使用するデータの準備
$entity = new Sample_Models_SampleEntity();
$entity->id = "new";
$entity->name = "new name";
$entity->description = "新しいデータ";
//新規データ、且つ変更済みを設定
$entity->isNew = true;
$entity->isModified = true;
//データ構造の準備
$property = new Sample_Models_SampleProperty();
//データソースインスタンス生成、接続
$datasource = CFW_Data_DataSourceFactory::getDataSource(array("name"));
try{
//接続する
$datasource->connect();
//データソースが扱うデータ構造を設定
$datasource->setProperty($property);
//保存実行
$result = $datasource->save($entity);
}
catch(Exception $ex){
$logger->error(__METHOD__,$ex->getMessage());
$logger->error(__METHOD__,$ex->getStack());
}
//後始末
$datasource->disconect();
save()を呼び出した時エンティティがnot isNew 且つ isModified の場合データを更新する。(対象が存在すれば、では無い)
//使用するデータの準備
$entity = new Sample_Models_SampleEntity();
$entity->id = "old";
$entity->name = "modify name";
$entity->description = "新しいデータを変更";
//Newではない
$entity->isNew = false;
//変更済み
$entity->isModified = true;
//データ構造の準備
$property = new Sample_Models_SampleProperty();
//データソースインスタンス生成、接続
$datasource = CFW_Data_DataSourceFactory::getDataSource(array("name"));
try{
$datasource->connect();
//データソースが扱うデータ構造を設定
$datasource->setProperty($property);
//保存実行
$result = $datasource->save($entity);
}
catch(Exception $ex){
}
//後始末
$datasource->disconect();
EntityPropertyクラスのcreatedAtField,modifiedAtFieldに指定された列についてはDataSourceオブジェクト内部でデータを設定して更新する。アプリケーションサイドで特別なことをやる必要は無い。ただし、doUpdate == falseに設定されている場合は更新しない。
既定ではそれぞれ"created_at","modified_at"だが、列名を指定することで他の列も設定可能
//使用するデータの準備
$entity = new Sample_Models_SampleEntity();
$entity->id = "old";
$entity->name = "modify name";
$entity->description = "新しいデータを変更";
$entity->createdAt = new Date("2001/2/3"); //無視されて現在日付が設定される
$entity->modifiedAt = new Date("2001/2/3"); //無視されて現在日付が設定される
$entity->isNew = true;
$entity->isModified = true;
//データ構造の準備
$property = new Sample_Models_SampleProperty();
//データソースインスタンス生成、接続
$datasource = CFW_Data_DataSourceFactory::getDataSource(array("name"));
try{
$datasource->connect();
//データソースが扱うデータ構造を設定
$datasource->setProperty($property);
//保存実行
$result = $datasource->save($entity);
}
catch(Exception $ex){
$logger->error(__METHOD__,$ex->getMessage());
$logger->error(__METHOD__,$ex->getStack());
}
//後始末
$datasource->disconect();
saveメソッドに渡したデータが配列(あるいはリスト)の場合、全てのデータについてisNew,isModifiedを確認して挿入|更新を実行する。
//使用するデータの準備
$entities = array();
//1件目
$entity = new Sample_Models_SampleEntity();
$entity->id = "new";
$entity->name = "new name";
$entity->description = "新しいデータ";
$entity->isNew = true; //新規データ
$entity->isModified = true;
$entities[] = $entity;
//2件目
$entity = new Sample_Models_SampleEntity();
$entity->id = "new2";
$entity->name = "modified";
$entity->description = "データ変更";
$entity->isNew = false; //既存データ
$entity->isModified = true;
$entities[] = $entity;
//...以下略
//データ構造の準備
$property = new Sample_Models_SampleProperty();
//データソースインスタンス生成、接続
$datasource = CFW_Data_DataSourceFactory::getDataSource(array("name"));
try{
$datasource->connect();
//データソースが扱うデータ構造を設定
$datasource->setProperty($property);
//保存実行
$result = $datasource->save($entities);
}
catch(Exception $ex){
$logger->error(__METHOD__,$ex->getMessage());
$logger->error(__METHOD__,$ex->getStack());
}
//後始末
$datasource->disconect();
isDeletedを設定したデータを削除する。
//使用するデータの準備
$entity = new Sample_Models_SampleEntity();
//この場合設定するのはキー情報だけでよい。
//通常はあらかじめfind()などで読み込んだデータを使う
$entity->id = "old";
$entity->isDeleted = true;
//データ構造の準備
$property = new Sample_Models_SampleProperty();
//データソースインスタンス生成、接続
$datasource = CFW_Data_DataSourceFactory::getDataSource(array("name"));
$datasource->connect();
//データソースが扱うデータ構造を設定
$datasource->setProperty($property);
//保存実行
$result = $datasource->save($entity);
//後始末
$datasource->disconect();
Criteriaオブジェクトを作成して選択条件とする。
table1.column1 = 'aaa' AND table1.column1 = 'bbb' を選択する。
//検索条件の設定
$criteria = new CFW_Data_Criteria();
$criteria->addWhere(new CFW_Data_Criteria_ColumnValueCondition( "table1.column1","aaa" ));
$criteria->addWhere(new CFW_Data_Criteria_ColumnValueCondition( "table1.column2,"bbb" ));
//ソート
$criteria->addOrderBy("table1.column2");
$criteria->addOrderBy("table1.column1");
//データ構造の準備
$property = new Sample_Models_SampleProperty();
//データソースインスタンス生成、接続
$datasource = CFW_Data_DataSourceFactory::getDataSource(array("name"));
try{
$datasource->connect();
//データソースが扱うデータ構造を設定
$datasource->setProperty($property);
//保存実行
$result = $datasource->find($criteria);
}
catch(Exception $ex){
$logger->error(__METHOD__,$ex->getMessage());
$logger->error(__METHOD__,$ex->getStack());
}
//後始末
$datasource->disconect();
データ選択条件を設定する
addWhere | WHERE条件を追加する |
addOrderBy | ORDER BY条件を追加する |
addHaving | HAVING条件を追加する |
addGroupBy | GROUP BY条件を追加する |
setLimit | 取得件数を設定する |
setOffset | 取得開始位置を設定する |
assemble | 追加された各条件をクエリーに使用できる形にする |
ColumnValueConditionを使う
//検索条件の設定
$criteria = new CFW_Data_Criteria();
//table1.column1 ='aaa'
$criteria->addWhere(new CFW_Data_Criteria_ColumnValueCondition( "table1.column1","aaa" ));
//table1.column2 in (1,10,100)
$criteria->addWhere(new CFW_Data_Criteria_ColumnValueCondition( "table1.column2,array(1,10,100),CFW_Data_Criteria::OPERATOR_IN));
ComplexConditionを使う
//検索条件の設定
// table1.column = 'xxx' or (table1.column1 = 'aaa' and table1.column2 in (1,10,100) ) を生成
$criteria = new CFW_Data_Criteria();
$complex = new CFW_Data_Criteria_ComplexCondition();
$complex->add(new CFW_Data_Criteria_ColumnValueCondition( "table1.column1","aaa" ))
$complex->add(new CFW_Data_Criteria_ColumnValueCondition( "table1.column2",array(1,10,100),CFW_Data_Criteria::OPERATOR_IN))
$criteria->addWhere(new CFW_Data_Criteria_ColumnValueCondition( "table1.column1","xxx" ));
$criteria->addWhereOr($complex);
DataSourceオブジェクトを作成してEntityオブジェクトに対する操作(save,find)を実行する。
Commandクラス(cfw.data.DataCommand (as),CFW_Data_Command(PHP)など)を使用する。パラメータはParameterオブジェクトを生成して追加する。*クエリー内に直接パラメータを埋め込まない
クエリー記述時、選択列に 「テーブル別名 + "__"(アンダースコア2個) + 元の列名」からなる別名をつける。TableRowオブジェクトまたはエンティティへの展開はEntityクラスのmap()メソッドを使用する。
//クエリーの組み立て
$query = "select
table1.column1 as table1__column1,
table1.column2 as table1__column2,
table1.column3 as table1__column3,
table1.column4 as table1__column4,
table2.column1 as table2__column1,
table2.column2 as table2__column2,
table2.column3 as table2__column3,
table2.column4 as table2__column4,
from table1 inner join table2
on table1.column1 = table2.column1
where table1.column1 = ?";
$command = new CFW_Data_Command($query);
$command->addParameter(new CFW_Data_Parameter(":column1",10));
//データ接続インスタンス生成
$connection = CFW_Data_ConnectionFactory::getConnection(array("name"));
$connection->connect();
//コマンドに接続を設定
$command->setConnection($connection);
//コマンド実行
$result = $command->executeQuery();
$connection->close();
//エンティティへの展開
$table1Entities = array();
$table2Entities = array();
foreach($result as $row){
//table1の処理
$table1Row = new Sample_Models_Table1Entity();
$table1Row->map($row,"table1");
$table1Entities[] = $table1Row;
//table2の処理
$table2Row = new Sample_Models_Table2Entity();
$table2Row->map($row,"table2");
$table2Entities[] = $table2Row;
}
以下の要素を1個または1個以上定義する。設定出来る項目は環境、データベース、使用言語等により異なる
名称(name) | 個々の接続先に名前をつける。階層構造は"/"あるいは"_"で区切ることで設定する。 |
クラス(class) | 実際に使用するConnecitonの実装クラスの名称。ex: SqlServer用、DbWebService用、SQLite用 etc... |
接続先(url | location) | データベース、Webサービスなどの接続先のurlまたはファイル名。 |
データベース名(database | dbname) | 接続するデータベースのインスタンス名、データベース名、etc... |
ユーザー(user) | データベース等を使用するためのユーザー名。 |
パスワード(password) | データベース等を使用するためのユーザー名。 |
quoteStyle | 文字列引用符処理の方法。シングルクォーテーションを二重化する(0,デフォルト)、その他 |
コマンドタイムアウト(commandTimeout) | 1個のコマンドを実行する際のタイムアウト時間(秒)。 |
接続タイムアウト(connectionTimeout) | 接続を開く際のタイムアウト時間(秒)。 |
オプション(option) | その他のオプション。実装クラスが定義する。 |
設定には必ずdefault接続先を設定しなければならない。
<!-- データアクセス設定 -->
<dataAccess defaultConnectionTimeout="15" defaultCommandTimeout="45">
<!-- 個々の接続 (default) "dbserver"上のSqlServerデータベースsampledbに接続する -->
<add name="default" className="CFW.Database.SqlServer.SqlServerConnection,CFW.Database"
url="dbserver" database="sampledb"
user="sampleuser"
password="samplepassword"
quoteStyle="0"
commandTimeout="15"
connectionTimeout="15"
option=""/>
<!-- 個々の接続 (サブシステム/機能単位) agサブシステムのデフォルト -->
<add name="ag/default" className="CFW.Database.SqlServer.SqlServerConnection,CFW.Database"
url="dbserver" database="sampledb"
user="sampleuser"
password="samplepassword"
quoteStyle="0"
commandTimeout="15"
connectionTimeout="15"
encryptUser="false"
option=""/>
<!-- 個々の接続 (サブシステム/機能単位) agサブシステムが使うmediaexデータベースへの接続 -->
<add name="ag/mediaex" className="CFW.Database.SqlServer.SqlServerConnection,CFW.Database"
url="dbserver" database="mediaex"
user="mediaex"
password="mediaex"
quoteStyle="0"
commandTimeout="15"
connectionTimeout="15"
encryptUser="false"
option=""/>
</dataAccess>
PHPの場合、名称は connection.name などのように設定要素に組み込まれている
//default接続先
connection.default.adapter = Sqlsrv //SQLサーバーに接続する
connection.default.params.host = dbserver
connection.default.params.username = sampleuser
connection.default.params.password = samplepassword
connection.default.params.dbname = sampledb
connection.default.params.driver_options.CharacterSet = utf-8 //sqlserverドライバに与えるオプション
//hotel/stay機能のための接続先
connection.hotel_stay.adapter = Sqlsrv //SQLサーバーに接続する
connection.hotel_stay.params.host = dbserver
connection.hotel_stay.params.username = sampleuser
connection.hotel_stay.params.password = samplepassword
connection.hotel_stay.params.dbname = hotel_stay
connection.hotel_stay.params.driver_options.CharacterSet = utf-8 //sqlserverドライバに与えるオプション
//hotel/credit機能のための接続先
connection.hotel_credit.adapter = Sqlsrv //SQLサーバーに接続する
connection.hotel_credit.params.host = dbserver
connection.hotel_credit.params.username = sampleuser
connection.hotel_credit.params.password = samplepassword
connection.hotel_credit.params.dbname = hotel_credit
connection.hotel_credit.params.driver_options.CharacterSet = utf-8 //sqlserverドライバに与えるオプション
以下の要素を1個または1個以上定義する。設定出来る項目は環境、データベース、使用言語等により異なる
名称(name) | 個々のデータソースに名前をつける。階層構造は"/"あるいは"_"で区切ることで設定する。 |
クラス(class) | 実際に使用するDataSource実装クラスの名称。ex: SqlServer用、DbWebService用、SQLite用 etc... |
接続先(connection) | 接続先設定に記述したname。ここでで指定する接続先以外に接続する場合は |
設定には必ずdefaultを設定しなければならない。
PHPの場合、名称は datasource.name などのように設定要素に組み込まれている
//default接続先
datasource.default.class = CFW_Data_DataSource
datasource.default.connection = default
例外処理が必要な場所に必要な処理を記述する。