BaseDAO(超α版)
CREATE TABLE `person` ( `id` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR( 50 ) NOT NULL , `email` VARCHAR( 50 ) NOT NULL , `year` int(11) NOT NULL default '0', `month` int(11) NOT NULL default '0', `day` int(11) NOT NULL default '0', PRIMARY KEY ( `id` ) );
[GlobalFilter] DBAccess = [DBAccess] dbtype = mysql dbserver = localhost dbname = demo dbuser = root dbpass = root
ほんの数行でDBとの連携を可能にするコンポーネントです。Actionクラスで例えばこのように書きます。
$personAll = $this->personDAO->find_all();
これでpersonAllを表示してみます。
array(4) {
0 => array(6) {
id => int 1
name => string(6) やまだ
email => string(16) yamada@test.info
year => int 2005
month => int 11
day => int 1
}
1 => array(6) {
id => int 2
name => string(2) 王
email => string(14) wong@balls.com
year => int 1940
month => int 5
day => int 20
}
2 => array(6) {
id => int 3
name => string(4) あべ
email => string(12) abe@test.com
year => int 1979
month => int 10
day => int 1
}
3 => array(6) {
id => int 4
name => string(4) 田中
email => string(14) tana@happy.com
year => int 2000
month => int 12
day => int 24
}
}
$personAllには4人分のデータが入っているのがわかります。しかし各データに割り振られているid、name、email、year、month、dayなどのハッシュキーはどこから現れたのでしょうか?
実はこのハッシュキーはマッピング設定ファイルで定義したものです。ではpersonDAOのマッピング設定ファイルの一部をお見せします。
[personDAO] map[id] = person.id map[name] = person.name map[email] = person.email map[year] = person.year map[month] = person.month map[day] = person.day primary = person.id
personDAOはマッピング設定ファイルのmap項目でマッピングされたテーブルのフィールドを取得して、設定されたハッシュキーを付けて返却しているということがわかると思います。つまりマッピング設定ファイルでは、actionクラスで使いたい値を設定すれば良いわけです。その使いたい値を生成してくれるpersonDAOの実態こそがBaseDAOなのです。それはマッピング設定ファイルの詳細を見ればわかると思います。
[DIContainer] personDAO = "component://db.BaseDAO" [personDAO] db = dicon://DBA map[id] = person.id map[name] = person.name map[email] = person.email map[year] = person.year map[month] = person.month map[day] = person.day primary = person.id
このマッピング設定ファイルというのは、まさにDI2の設定ファイル、いわゆるdicon.iniファイルそのものなんです。
設定ファイルなどとmaple固有の話が続いたので、純粋にBaseDAOだけに関係した流れをコードで示してみます。require_onceのパスを各環境に合わせれば、このコードだけでBaseDAOが動きます。あらかじめ用意されたメソッドを試してみましょう。
<?php
require_once("Db_BaseDAO.class.php");
require_once("../../../maple/core/DBAccess.class.php");
//なんちゃってlogger
class LogFactory{
function LogFactory(){
}
function trace($mes,$meth){
$this->_disp($mes,$meth);
}
function error($mes,$meth){
$this->_disp($mes,$meth);
}
function _disp($mes,$meth){
$output_code = "SJIS";
$internal_code = "EUC-JP";
$mes = mb_convert_encoding($mes, $output_code,$internal_code);
$meth = mb_convert_encoding($meth, $output_code,$internal_code);
var_dump($mes."-".$meth);
}
function getLog(){
$log = new LogFactory();
return $log;
}
}
//接続設定ファイル(maple.ini)相当
$dbtype = "mysql";
$dbserver = "localhost";
$dbname = "demo";
$dbuser = "root";
$dbpass = "root";
//マッピング設定ファイル(dicon.ini)相当
$map['id'] = "person.id";
$map['name'] = "person.name";
$map['email'] = "person.email";
$map['year'] = "person.year";
$map['month'] = "person.month";
$map['day'] = "person.day";
$primary = "person.id";
//フィルター相当
$dba = new DBAccess();
$dba->setDbtype($dbtype);
$dba->setDbserver($dbserver);
$dba->setDbname($dbname);
$dba->setDbuser($dbuser);
$dba->setDbpass($dbpass);
$connect = $dba->connect();
//DI相当
$person = new Db_BaseDAO();
$person->setDb($connect);
$person->setMap($map);
$person->setPrimary($primary);
//アクションクラス相当
$personAll = $person->find_all();
?>
$conditionには
$condition = "person.name = 山田";
のようにwhere句相当の検索条件を与えます。 AND検索をする場合は
$condition[] = "person.name = 山田"; $condition[] = "person.year = 1999";
などのように配列にして渡します。
全取得
primaryで指定したフィールド名 = $id を取得
map配列内にマッピング設定ファイルでprimary指定したハッシュキーの値が存在する場合はupdate処理、ない場合は新規にinsertします。これ言葉でちょっと説明が難しいのでexample2DBを参照してくださいな
primaryで指定したフィールド名 = $id を消去
次は1対多関係であるような以下のような場合を取り上げます。
[porson] 1---* [category]
create table category( id int(11) not null auto_increment, name varchar(20), primary key (id) ); CREATE TABLE person ( id int(11) NOT NULL auto_increment, name varchar(50), email varchar(50), year int(11), month int(11), day int(11), category_id int(11), PRIMARY KEY (id) )
[DIContainer] person = "component://db.BaseDAO" [person] db = dicon://DBA map[id] = person.id map[name] = person.name map[category] = category.name primary = person.id relation = "person.category_id = category.id"
あらかじめ各テーブルに値をセットして試してみると、テーブルが外部結合され値が取得されているのがわかると思います。追加したコードは、設定ファイルの
relation = "person.category_id = category.id"
だけです。このようにテーブルをまたいでマッピングされたBaseDAOに対しても今までと同じようにsaveメソッドが使えます。その場合はprimaryキーのあるテーブルに対してのみデータの保存を行います。