DAO generator for PHP and MySQLを使ってみた No.2

前回の記事の続きです。

最後にちょっと疑問が残ってました。


各テーブル毎にクラスを自動的に生成し、クエリ結果をそのクラスとして返却する。
では、テーブルをJOINした場合には・・・??

で、やってみた。


まずは、DB周り。

  • booksのauthorカラムをauthoridに変更(カラム名+型)
CREATE TABLE `books` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(50) DEFAULT NULL,
  `authorid` int(11) NOT NULL,
  `yearofpublication` int(11) DEFAULT NULL,
  `publisher` varchar(50) DEFAULT NULL,
  `price` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
)
  • サンプルデータ
INSERT INTO `books` VALUES 
(1,'Annabel Lee',1,1849,'The Literature Page',256),
(2,'The Ballad of Reading Gaol',1,1898,'The Literature Page',475),
(4,'Winnetow',2,1956,'The truth',123),
(5,'JBoss Tools 3',0,2009,'Packt',569);
  • 新規にauthorテーブル(筆者)を用意
CREATE TABLE `author` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
)
  • サンプルデータ
INSERT INTO `author` VALUES 
(1,'viva','2000-10-10',20),
(2,'debit','1999-01-01',45);


この状態で、generate.phpを実行。※設定は、前回のまま。

出来たファイルは、これ。

  • AuthorMySqlExtDAO.class.php
  • BooksMySqlExtDAO.class.php

で、BooksMySqlExtDAO.class.phpに以下のメソッドを追加。

<?php
public function queryBooksAndAuthor(){
    $sql = "SELECT * FROM books LEFT JOIN author ON authorid = author.id";
    $sqlQuery = new SqlQuery($sql);
    return $this->getList($sqlQuery);
}

で、こいつを呼び出した結果は・・・

<?php
object(Book)#6 (6) {
  ["id"]=>
  string(1) "1"
  ["title"]=>
  string(11) "Annabel Lee"
  ["authorid"]=>
  string(1) "1"
  ["yearofpublication"]=>
  string(4) "1849"
  ["publisher"]=>
  string(19) "The Literature Page"
  ["price"]=>
  string(3) "256"
}
object(Book)#7 (6) {
  ["id"]=>
  string(1) "1"
  ["title"]=>
  string(26) "The Ballad of Reading Gaol"
  ["authorid"]=>
  string(1) "1"
  ["yearofpublication"]=>
  string(4) "1898"
  ["publisher"]=>
  string(19) "The Literature Page"
  ["price"]=>
  string(3) "475"
}
・・・

あっやっぱり。


返って来るのは、あくまでもBookオブジェクトか。

必ずテーブルのクラスだという事を保障する代わりにSQLの自由度が落ちている。

これじゃJOINするとき、毎回アプリ側でやらないといけないの!?!?

めんどくさっ。


改造してみる。


こいつが原因の箇所。

<?php
protected function readRow($row){
    $book = new Book();

    $book->id = $row['id'];
    $book->title = $row['title'];
    $book->authorid = $row['authorid'];
    $book->yearofpublication = $row['yearofpublication'];
    $book->publisher = $row['publisher'];
    $book->price = $row['price'];

    return $book;

おもいっきり固定じゃん。
で、改造版がこれ。

<?php
protected function readRow($row){
    $book = new Book();

    $keys = array_keys($row);
    foreach ($keys as $key) {
        $book->$key = $row[$key];
    }

    return $book;

配列のkey = Bookオブジェクトのプロパティって感じに。


これで、さっきと同じメソッドを呼び出してみる。

<?php
object(Book)#6 (19) {
  ["id"]=>
  string(1) "1"
  ["title"]=>
  string(11) "Annabel Lee"
  ["authorid"]=>
  string(1) "1"
  ["yearofpublication"]=>
  string(4) "1849"
  ["publisher"]=>
  string(19) "The Literature Page"
  ["price"]=>
  string(3) "256"
  ["0"]=>
  string(1) "1"
  ["1"]=>
  string(11) "Annabel Lee"
  ["2"]=>
  string(1) "1"
  ["3"]=>
  string(4) "1849"
  ["4"]=>
  string(19) "The Literature Page"
  ["5"]=>
  string(3) "256"
  ["6"]=>
  string(1) "1"
  ["7"]=>
  string(4) "viva"
  ["name"]=>
  string(4) "viva"
  ["8"]=>
  string(10) "2000-10-10"
  ["birthday"]=>
  string(10) "2000-10-10"
  ["9"]=>
  string(2) "20"
  ["age"]=>
  string(2) "20"
}
・・・

あれ?長くね?

これは、見たことがありますっ!
SQLの結果を取得するとこのオプションの問題。

mysql_fetch_array

なので、grepで探して変更。

generated/class/sql/QueryExecutor.class.php

<?php
public static function execute($sqlQuery){
        $transaction = Transaction::getCurrentTransaction();
        if(!$transaction){
                $connection = new Connection();
        }else{
                $connection = $transaction->getConnection();
        }
        $query = $sqlQuery->getQuery();
        $result = $connection->executeQuery($query);
        if(!$result){
                throw new Exception(mysql_error());
        }
        $i=0;
        $tab = array();
★        while ($row = mysql_fetch_array($result, MYSQL_ASSOC)){
                $tab[$i++] = $row;
・・・

これで取得した結果は。

<?php
object(Book)#6 (9) {
  ["id"]=>
  string(1) "1"
  ["title"]=>
  string(11) "Annabel Lee"
  ["authorid"]=>
  string(1) "1"
  ["yearofpublication"]=>
  string(4) "1849"
  ["publisher"]=>
  string(19) "The Literature Page"
  ["price"]=>
  string(3) "256"
  ["name"]=>
  string(4) "viva"
  ["birthday"]=>
  string(10) "2000-10-10"
  ["age"]=>
  string(2) "20"
}

OK。

使ってみて。
まだまだ、改良が必要な気がするが、templatesファイルがあるので、カスタム可能である。
また、開発初期の段階での導入には、コーディングミス軽減・繰返し作業の効率化などの点で優れている。既存システムには、導入が難しい(システムの解析が大変)のではないかと思う。


以上、DAO generator for PHP and MySQL を使ってみた。でしたー。