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キーのあるテーブルに対してのみデータの保存を行います。