データベースアクセスの基本
モデルプログラミングの説明に入る前に、Perlでデータベースへのアクセスを行うための仕組みについて説明します。
Perlによるデータベースへのアクセス
Perlからデータベースにアクセスする一般的なやり方では、DBIとDBDを使用します。DBIとは、データベースへの操作を抽象化したインターフェースを提供するモジュールで、さまざまなデータベースにアクセスする場合でも、同じようなコードを記述できます。そして接続するデータベースに依存した処理を実装しているのがDBDドライバモジュールになります。DBDには接続するデータベースによってさまざまなモジュールが提供されています。
主なDBDモジュールには次のものがあり、オープンソースのDBMS以外にも、Oracleなどの商用DBMSに接続するためのドライバも公開されています。
| DBDモジュール | 説明 |
| DBD::SQLite | SQLite用ドライバ |
| DBD::Pg | PostgreSQL用ドライバ |
| DBD::mysql | MySQL用ドライバ |
| DBD::Oracle | Oracle用ドライバ |
| DBD::DB2 | IBMのDB2用ドライバ |
| DBD::ODBC | ODBC接続用ドライバ |
DBIx::Class
DBI/DBDを使用したプログラムでは直接SQL文を記述することになりますが、オブジェクト指向言語を使用した最近のフレームワークあたりでは、クラスとデータベースのテーブルを結びつけるO/Rマッパ(オブジェクト/リレーショナルマッパ)を利用することが増えています。PerlでもO/Rマッピングを行うためのモジュールとしていくつか公開されていますが、ここではDBIx::Classを紹介します。
DBIx::ClassではDBIx::Class::Schemaを使用して、Perlのクラスとデータベースのテーブルの関連づけを行いますが、テーブルに対応するクラスは開発者が作成する必要があります。このテーブルに対応するクラスを動的に生成してくれるモジュールとして、DBIx::Class::Schema::Loaderが公開されています。DBIx::Class::Schema::Loaderを使用すれば、あらかじめテーブルに対応するクラスをわざわざ作成しなくても、対象となるデータベースのテーブル構造などを解析して、必要なクラスを動的に作成してくれるようになります。
Catalyst::Model::DBIC::Schema
Catalystのモデルモジュールとして、前述のDBIx::Class::SchemaとDBIx::Class::Schema::Loaderを使用するCatalyst::Model::DBIC::Schemaモジュールが公開されています。
Catalyst::Model::DBIC::Schemaを使用してモデルを作成するには、ビューなどと同様に「<MyApp>_create.pl」ヘルパスクリプトを使用します。このヘルパスクリプトに渡す最低限必要なパラメータは次のようになります。
$ <MyApp>_create.pl model モデル名 DBIC::Schema スキーマクラス名 create=static | dynamic 接続情報
createにはstaticとdynamicを指定できますが、現在、dynamicは非推奨となっています。これらのオプションによる違いは、staticの場合には、ヘルパスクリプト実行時にテーブルに対応するクラスファイルを生成するのに対して、dynamicの場合にはファイルは生成されず、実行時に動的にメモリ上に作成されます。これ以外のオプションについては、Catalyst::Helper::Model::DBIC::Schemaを参照ください。
MyAppアプリケーションに、MySQLのデータベースに定義されたテーブルをモデルとして作成する例を見てみましょう。この例では、MySQLのデータベース「sampledb」には、UserテーブルとEntryテーブルが定義されているものとします。またsampledbに接続するためのユーザー名とパスワードとして、それぞれ「myusername」と「mypassword」を指定しています。
$ ./MyApp/script/myapp_create.pl model MyDB DBIC::Schema \ MyApp::Schema create=static \ dbi:mysql:sampledb myusername mypassword
このコマンドを実行すると、「MyApp/lib/MyApp」フォルダ以下に、次のファイルが作成されます。
| 作成されるモジュールファイル | 説明 |
| Model/MyDB.pm | sampledbへの接続情報を持ったモデルクラス |
| Schema.pm | DBIx::Class::Schemaを継承したスキーマクラス |
| Schema/Result/User.pm | Userテーブルに対応するクラス |
| Schema/Result/Entry.pm | Entryテーブルに対応するクラス |
UserテーブルにはINTEGER型の主キー制約がついたidというカラムが定義されているとすると、コントローラからid=1のUser情報を取得するには次のようなコードを記述します。
sub index :Path :Args(0) {
my ( $self, $c ) = @_;
my $user = $c->model('MyDB::User')->find(1);
$c->response->body($user->name);
}
「$c->model」メソッドに引数として、”モデル名”::”テーブルに対応するクラス名”を指定すると、テーブルに対する操作を扱うDBIx::Class::ResultSetを返します。このクラスには主キーの値を指定すると、マッチするレコードを表すオブジェクトを返すfindメソッドが定義されているので、こちらを使用して値を取得しています。結果として返されるオブジェクトは、テーブルに対応するクラスのインスタンスとなっており、カラム値にアクセスするためのメソッドがあらかじめ定義されています。よってUserテーブルのnameカラムの値を取得するには「$user->name」のように記述できます。
