アマゾン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 distribution
Type '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. 1 Trackback(s)

  2. Nov 27, 2008: 「蔵書管理システム」というより「書籍情報管理システム」かな? | Yama's Memorandum

Post a Comment