アマゾン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)