アマゾンAPIを活用した蔵書管理システム(4)
November 22, 2008 – 1:30 pm前回エントリー(「アマゾンAPIを活用した蔵書管理システム(3)」)で、アマゾンから取得した書籍データを我がサーバ上のデータベースに取り込む方法について記述した。今回は、前回作成したデータベースSampleDBからデータを抽出・取り出す方法について説明する。
複数のテーブルを含むDBの取り扱い: もう2ヶ月も前になるが、「蔵書管理システムを作成してみた」を書き、そこで簡単な書籍検索用のWebプログラムを作ってみた。このWebプログラムのデータベースはテーブルひとつで構成されており、クエリも単純なものですんだ。これに対し、前回の「蔵書管理システム(3)」で作成したデータベースは複数、7種類のテーブルから構成されている。
複数のテーブルはどのように取り扱えばいいかいろいろ調べてみた。JOIN句とかなんとかいろいろ説明してあるが今ひとつしっくりこない。最も安直な方法は、対象とするテーブル全てをカンマで並べ、WHERE句で関連するテーブルのカラムを結びつけることのようだ。この方法、データベースの扱いとして正しい方法かどうかさだかではないが、私のような初心者にとっては最も考えやすい。
テーブルを結合したSELECT文: ということで、著者名をキーとしてデータベースに登録されている書籍を抽出するSELECT文を書いてみることにした。具体的には、前回作成したSampleDBから著者名「ドーキンス」が含まれる書籍を抽出し、テーブルbook上のidと書籍タイトル(title)を求めてみる。実際のクエリー文は以下のようになる:
SELECT book.id,book.title FROM book, binding, currency, publisher, book_author, author WHERE book.binding_id=binding.id AND book.currency_id=currency.id AND book.publisher_id=publisher.id AND book.id = book_author.book_id AND author.id = book_author.author_id AND author.author like '%ドーキンス%';
これを実行してみる:
%mysql –u user_name –p SampleDB Enter password: password Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 497 Server version: 5.0.45 Source distributionType 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> SELECT book.id,book.title -> FROM book, binding, currency, publisher, book_author, author -> WHERE book.binding_id=binding.id AND -> book.currency_id=currency.id AND -> book.publisher_id=publisher.id AND -> book.id = book_author.book_id AND -> author.id = book_author.author_id AND -> author.author like '%ドーキンス%'; +----+--------------------------------------+ | id | title | +----+--------------------------------------+ | 1 | 利己的な遺伝子 (科学選書) | | 2 | 盲目の時計職人 | +----+--------------------------------------+ 2 rows in set (0.00 sec) mysql> quit; Bye
となり、期待したとおり、「リチャード・ドーキンス」を著者とする2冊の書籍データが返されてきた。
DAOのメソッドの作成とサンプルプログラムの作成: ということで、前回作成したDAO(BookDao.php)のメソッドとして、上記したクエリー文を含むものを作成することにした。作成するにあたっての注意点は、抽出される書籍に複数の著者名(共著者、翻訳者)が含まれることだろう。このあたりを注意しながらBookDaoのメソッドgetBookAuthorByAutor()を作成した。このメソッドの戻り値は、「蔵書管理(2)」のサンプルと同様、2種類のデータオブジェクト(DTO:Book, Author)を配列として一まとめにパックする形式とした。
このメソッドを用いる例を以下に示してみよう。なお、ここで用いるメソッドgetBookAuthorByAuthor()のソースはこのブログの最後に掲げる。
Sample.php:
<?php require_once("Book.php"); require_once("Author.php"); require_once("BookDao.php"); $author_name = "ドーキンス"; $bookdao = new BookDao(); $ret=$bookdao->getBookAuthorByAuthor($author_name); echo "No. of Book retrieved = " . sizeof($ret)/2 . "\n"; for ($i=0; $i<(sizeof($ret)/2+1); $i+=2) { $book = $ret[$i]; $author_array = $ret[$i+1]; echo "Title = " . $book->getTitle() . "\n"; echo " ISBN=".$book->getIsbn()." ASIN=".$book->getAsin()." EAN=".$book->getEan(). "\n"; echo " Publisher: " . $book->getPublisher() . "\n"; echo " Publication Date:" . $book->getPubdate() ."\n"; for ($j=0; $j<sizeof($author_array); $j++) { echo " Author = ".$author_array[$j]->getAuthor() ."[" . $author_array[$j]->getRole() . "]\n"; } echo "\n"; $book = NULL; $author_array = NULL; } $bookdao = NULL; ?>
このSample.phpを実行すると:
% php Sample.php No. of Book retrieved = 2 Title = 利己的な遺伝子 (科学選書) ISBN=4314005564 ASIN=4314005564 EAN=9784314005562 Publisher: 紀伊國屋書店 Publication Date:1991-02-00 Author = リチャード・ドーキンス[] Author = 日高 敏隆[翻訳] Author = 岸 由二[翻訳] Author = 羽田 節子[翻訳] Author = 垂水 雄二[翻訳]Title = 盲目の時計職人 ISBN=4152085576 ASIN=4152085576 EAN=9784152085573 Publisher: 早川書房 Publication Date:2004-03-24 Author = リチャード・ドーキンス[] Author = 日高 敏隆[翻訳]
となる。
=============
メソッドgetBookAuthorByAuthor()のソースを以下に示す。このソースを前回「蔵書管理(3)」の最後に示したBookDao.phpに組み込むことになる:
// Get book and author by Author public function getBookAuthorByAuthor($ask_author) { $ret_array = array(); $book_author_array = array(); is_null($this->mysqli) and $this->connect(); $sql = "SELECT book.id,book.isbn,book.asin,ean,title,image_url,pubdate," . "price,pages,publisher.publisher,binding.binding,currency.currency_cd " . "FROM book, binding, currency, publisher, book_author, author " . "WHERE book.binding_id=binding.id AND " . " book.currency_id=currency.id AND " . " book.publisher_id=publisher.id AND " . " book.id = book_author.book_id AND " . " author.id = book_author.author_id AND " . " author.author like '%" . $ask_author . "%'"; $result = $this->mysqli->query($sql); $book_array = array(); while($row = $result->fetch_array(MYSQLI_ASSOC)) { $book = new Book(); $book->setId($row["id"]); $book->setIsbn($row["isbn"]); $book->setAsin($row["asin"]); $book->setEan($row["ean"]); $book->setTitle($row["title"]); $book->setImage_url($row["image_url"]); $book->setPubdate($row["pubdate"]); $book->setPrice($row["price"]); $book->setPages($row["pages"]); $book->setPublisher($row["publisher"]); $book->setBinding($row["binding"]); $book->setCurrency_cd($row["currency_cd"]); $book_array[] = $book; $sql_author = "SELECT author,role " . "FROM book, book_author, author, role " . "WHERE book.id=book_author.book_id AND " . " author.id=book_author.author_id AND " . " role.id=book_author.role_id AND " . " book.id = '" . $row["id"] . "'"; $result_author = $this->mysqli->query($sql_author); $author_array = array(); while($row_author = $result_author->fetch_array(MYSQLI_ASSOC)) { $author = new Author(); $author->setAuthor($row_author["author"]); $author->setRole($row_author["role"]); $author_array[] = $author; } $result_author->close(); $book_author_array[] = $book; $book_author_array[] = $author_array; } $result-> close(); return $book_author_array; }
1 Trackback(s)