トップページ >  perl >  Catalystでデータベースへアクセスする
初版2012/05/22: 最終更新日2012/05/22
Catalystでデータベースへアクセスする
目次
概要
Perlでの一般的なデータベースアクセス
PerlのO/Rマッピング
CatalystでO/Rマッピングを利用する
概要
PerlのWebアプリケーションフレームワークであるCatalystは、MVCモデルを用いています。
データベース(MySQL、PostgreSQLなど)へ接続する場合は、このM(モデル)と通して接続します。

ここでは、Perlでの一般的なデータベースアクセスの方法を簡単に説明した後に、
フレームワークであるCatalystで最近よく用いられているデータベースへのアクセス方法までを説明します。

Perlでの一般的なデータベースアクセス
Perlのアプリケーションからデータベースへ接続する場合、
一般的にはDBIモジュールを使用します。
DBIモジュールの詳細については、CPAN(Perlのモジュールが登録されているサイト)で検索してみるか、
すでにインストールされている環境であれば、

shell> perldoc DBI

としてみてください。
perldoc は、Perlについての色々なドキュメントを参照するためのコマンドです。

DBIモジュールがインストールされていない方は、

shell> perl -MCPAN -e shell

というコマンドで、CPANシェルを立ち上げ、DBIモジュールをインストールしてみてください。

DBIモジュールとは、データベースの操作を抽象化したクラスで、
実は、データベースを扱うには、それぞれのデータベースに特化した、
ドライバのモジュールが必要となります。

MySQLであれば、DBD::mysql、PostgreSQLであれば、DBD::Pg というように、
それぞれのデータベース対して、ドライバモジュールが準備されております。


一般的には、これらのドライバモジュールと、
データベース操作の抽象化された DBIモジュールを利用して、Perlからデータベースを操作する事となります。

PerlのO/Rマッピング
データベースへのアクセスを抽象化したDBIモジュールでも、データベースを扱う事は出来ますが、
Perlのオブジェクトを各データベースのテーブル、レコードへと関連付け、扱いやすくするやり方があります。

それが O/Rマッピングと呼ばれています。

O/Rマッピングの方法を用いて実装されているモジュールが、各言語にも存在しており、
Perlでも「Class::DBI」や「DBIx::Class」といったように、O/Rマッピングを利用したモジュールが
用意されております。

数年前までは Class::DBI が主流でしたが、
最近では DBIx::Class が主に用いられており、通称「DBIC」と呼ばれております。

DBIx::Class をインストールする際も、上記で説明したDBIと同様に、


shell> perl -MCPAN -e shell DBIx::Class

とする事で、インストールする事が可能です。

ここで注意が必要なのですが、
DBIや、各データベースドライバ(DBD::mysql)などを先にインストールしておく事をオススメします。
DBIx::Class のインストールでも、同時にインストールされますが、
しばしば、インストールが失敗する事がありますので、
個別に先にインストールを実行し、どこで失敗しているかの切り分けをし易くしておくのが便利です。


DBIx::Class を利用する際には、
データベースの構成を示す「DBIx::Class::Schema」のサブクラスと、
テーブル毎に対応した DBIx::Class ののサブクラスを作る必要があります。

テーブル構成を下記のようなものだったとしましょう。
CREATE TABLE books (
    id   int(11) auto_increment not null primary key,
    name varchar(255)
    );
※データベース名は「book」を想定。
※MySQLを想定して CREATE TABLE 文を記載しております。

DBIx::Class::Schema を継承したサブクラスはこのようになります。
book テーブルを扱うプロジェクトを 「Book」とした場合は、
「Book::Schema」という名前で作成するのが一般的です。
package Book::Schema;
use base qw/DBIx::Class::Schema/;

# load all Blog::Schema::* automatically
__PACKAGE__->load_classes();

1;

DBIx::Class を親として、load_classes メソッドを呼ぶだけです。

次に、テーブルに対応したクラスを作成します。
package Book::Schema::Books;
use strict;
use warnings;
use base qw/DBIx::Class/;

my $table   = 'books';
my @columns = qw(id name);

__PACKAGE__->load_components(qw/Core/);
__PACKAGE__->table($table);
__PACKAGE__->add_columns(@columns);
__PACKAGE__->set_primary_key($columns[0]);

1;
このようにテーブルに対応したクラスを作成します。

また、上記までのものを利用し、
実際にデータベースにアクセスするためのコードは次のようになります。

use Book::Schema;

# 接続
my $schema = Book::Schema->connect('dbi:mysql:book', 'user', 'password');

# テーブルに対するオブジェクトを取得
my $books = $schema->resultset('Books');

# 1レコードずつ取り出す例
while (my $book = $books->next) {
	print $book->id, "\n";
	print $book->name, "\n";
}

SQL文を利用せず、オブジェクトを扱うようにデータベースを扱う事が可能となります。

CatalystでO/Rマッピングを利用する
それでは、実際にPerlのWEBアプリケーションフレームワークである、Catalystで利用した場合はどうなるのか見ていきましょう。

Catalyst では、
Catalyst::Model::DBIC::Schema というモジュールが用意されています。

Catalystにはヘルパースクリプトが用意されているため、
前述したような各クラスを自動で作成してくれます。

前述のBookプロジェクトを参考に説明すると、このようになります。

Book_create.pl model BookDB DBIC::Schema Book::Schema create=static \
  dbi:mysql:book user password
このコマンドを実行すると、
各クラスのモジュールが自動で作成されます。


Book/Model/BookDB.pm
- book データベースへの接続情報
Book/Schema.pm
- DBIx::Class ::Schema を継承したクラス
Book/Schema/Result/Books.pm
- books テーブルに対応するクラス

DBIx::Class ではテーブル名は始めの文字を大文字、「_(アンダーバー)」で名前が区切られている場合も、
その区切りの始めの単語を大文字にした名前を利用します。

例えば
books テーブルの場合は、「Books」
books_user テーブルの場合は、「BooksUser」のようになります。

booksテーブルから情報を取得する際は、
下記のように記載します。

id 「1」の情報を取得する場合。
sub index :Path :Args(0){
	my ($self, $c) = @_;
	my $books = $c->model('BookDB::Books')->find(1);
	$c->response->body( $books->name );
}

$c->model メソッドに引数として、"モデル名"::"テーブルに対応するクラス名"を指定します。

テーブルを扱う「DBIx::Class::Result」を返しますので、
あとは、DBIx::Class と同じように利用する事が可能です。

各カラムへは、カラム名をメソッドとして呼び出す事でアクセスできます。

最近の流行は、このように DBIx::Class モジュールを利用し、
Catalyst の Model 部分を実装する流れとなっています。