S2Ethnaを使って見る 〜その2〜
S2Container.PHP5のサンプルはMaple使ってたこともあり
ソース読んで理解した。
解らん人は CodeZine:S2Container.PHP5を用いたDIベースの開発を見ると解るかも
その後のサンプルを実行する為に
以下のようなDBを用意した。
HOST :localhost DB :s2ethna USER :hoge PASS :hoge
DB設定の定義行っている場所が2箇所あった
- s2ethna-ini.php
<?php $config = array( /* 中略 */ // デモンストレーション 'demonstration' => false, 'demonstration_dsn' => 'mysql://hoge:hoge@localhost/s2ethna', 'demonstration_page' => '1',
これ替えなくても動くみたい。。。どんな時に使ってるんだろうか。。。*1
- pdo.dicon
<component name="dataSource" class="S2Ethna_PDODataSource"> <property name="dsn">"mysql:host=localhost; dbname=s2ethna"</property> <property name="user">"hoge"</property> <property name="password">"hoge"</property> <property name="option"> array(PDO::ATTR_ORACLE_NULLS => PDO::NULL_EMPTY_STRING, PDO::ATTR_AUTOCOMMIT => false); </property> </component>
ひとまず、上記のようにを変更した。
AppManagerでDAOを利用する
S2Dao.PHP5サンプル|AppManagerでDAOを利用する|解説
項番1.の通りに以下のSQLを実行するとエラーとなる。。。
CREATE TABLE `cd` ( `ID` INT NOT NULL , `TITLE` VARCHAR(100) , `CONTENT` VARCHAR(200) , PRIMARY KEY (`ID`) )TYPE=InnoDB; CREATE TABLE `shelf` ( `ID` INT NOT NULL AUTO_INCREMENT , `CD_ID` INT NOT NULL , `ADD_TIME` DATETIME DEFAULT '2005-12-25 10:12:13' , PRIMARY KEY (`CD_ID`, `ID`) , INDEX (`CD_ID`) , CONSTRAINT `FK_shelf_1` FOREIGN KEY (`CD_ID`) REFERENCES `cd` (`ID`) )TYPE=InnoDB; BEGIN; INSERT INTO `cd` ( ID, CONTENT, TITLE ) VALUES ( 1, 'hello!!', 'S2Dao!!!' ) ; INSERT INTO `shelf` ( CD_ID, ADD_TIME ) VALUES ( 1, '2005-12-18 10:12:34' ) ; COMMIT;
1075 Incorrect table definition; there can be only one auto column and it must be defined as a key
あれこれいじってみると、原因はPK定義の順序が悪かったらしい
CREATE TABLE `shelf` ( `ID` INT NOT NULL AUTO_INCREMENT , `CD_ID` INT NOT NULL , `ADD_TIME` DATETIME DEFAULT '2005-12-25 10:12:13' , PRIMARY KEY (`ID`,`CD_ID`)
CD_IDとIDの順序を入れ替えてあげればOK
早速、ブラウザで動作確認するとちゃんと動きましたー
BeanとDaoの定義さえ完了してaspectすれば、↓だけで動くとのはすばらしいっ!
<?php function getCdList() { return $this->dao->readCdList(); }
以下の2ファイル内容が一緒だが、AppManagerにDIしていて
dao.diconは使われていない。
- app/S2ethna_ExampleDaoManager.dicon
- app/action/Example/Di/dao.dicon
試しにActionClassにDIしてみた。
<?php /** * example_daoアクションの実装 * * @access public * @return string 遷移名 */ function perform() { //$list = $this->backend->getManager('ExampleDao')->getCdList(); // 【追記】直接daoのメソッドを利用するように変更した。 $list = $this->dao->readCdList(); $this->af->setApp('cdlist',$list); return 'example_dao'; } // 【追記】DIを受け取る private $dao; function setCdDao(CdDao $dao) { $this->dao = $dao; }
おぉ動いた。EthnaのAppManagerを使う意味を考えるとこんな絶対使い方しませんが・・・
電子掲示板
S2Dao.PHP5サンプル|電子掲示板|解説|S2Ethna v0.2
項番1のSQLを実行して早速、ローカルの掲示版アプリを早速見る。
トランザクションを行うため、interfaceを用意し、AppManagerに実装させます。
ん〜、若干めんどくさいような。あとから見たときの解り安さとトレードというところでしょうか?
しかし、ページャー便利ねーDBレイヤーと連動してて無駄がない。。。
今後、調査する項目
複数テーブルに対してのトランザクションの実行処理を作って見る。
S2Container.PHP5の仕様により、$this->createArticleと呼ぶとトランザクションがかかりません。外部から呼んでください。
複数のAppManagerを跨いでトランザクションをかけたい場合は、S2Ethna_PDODataSourceの解説をご覧ください。
色々と制約もあるようですし、何より。。想像が付かないのでseasarの慣れがてらやってみることにします。
複数DBの定義を試す
DB周りはレプリケーションして実装したいので、以下のリンクの方法を試してみる。
S2で複数DBとのコネクションを取得する方法は?|FAQ/S2DAO - SeasarWiki
負荷分散の為にテーブルをインクリメンタルに数字を増やしていった場合の対処
負荷が予想されるので以下のようなことを行おうと検討中*2
親ID が 1 〜 10000 の時は 子table_00に
親ID が10001 〜 20001 の時は 子table_01に
参照はviewで何とかなるとして、更新系はどうしたもんか・・・
都度、beanとDaoを作るのも無駄な気がするのでどうしたものか考える
実際ここまでくるとS2だとどうなるんだろうなぁ・・・
○TechTargetジャパン:mixiの生みの親“バタラ氏”が語るMySQLの意外な利用法
想像がつかない。。。
今日気になった物
[rakuten:foronefirst:10002062:detail]
これがあったら仕事の効率上がるだろうなぁ・・・1時間毎に期限を設けて目標を立てて自らを追い込めるし