created: 2022-04-01T07:16:41.000Z

Perl での、抽象的な DBIx::Class のレイヤーからRDBMS寄りな DBI のレイヤーまでの役割

DBIx::Class::Schema クラス

データベースのテーブルを抽象したクラスを、ORMオブジェクトとして使えるようにするためのクラス。

これを継承したクラスを定義して以下のように使い始める。

package Library::Schema;
use base qw/DBIx::Class::Schema/;
 
# load all Result classes in Library/Schema/Result/
__PACKAGE__->load_namespaces();
 
package Library::Schema::Result::CD;
use base qw/DBIx::Class::Core/;
  
# Elsewhere in your code:
my $schema1 = Library::Schema->connect(
  $dsn,
  $user,
  $password,
  { AutoCommit => 1 },
);
my @dvd_objects = $schema2->resultset('CD')->search( ... );

$schema1 というオブジェクトはORMクラスにアクセスするためのインターフェースで、ORMクラスはテーブルとレコードを抽象化したメソッドを提供している。たとえば、ORMオブジェクトのカラムに値を代入して update メソッドを読んだらSQLのUPDATE文が発行される。

この $schema1 オブジェクトから DBI のインスタンスにアクセスするのはこういう段取りになる。

$schema1->storage->dbh;

storage とは DBIx::Class::Storage::DBI のインスタンスである。

DBIx::Class::Storage::DBI

これは last_insert_id や、datetime_parser など、データベースと (もっと抽象的な)DBIx のテーブル定義との橋渡しをするクラスのようだ。

dbh_dodisconnect といったメソッドもあるので、DBI でできることもここでできるようになっている。

DBIとサブクラス

DBI はデータベースの操作を抽象化したクラス群である。抽象化といっても DBIx が担当しているレイヤーよりはだいぶ生のデータベース寄りの具体的なもので、たとえば接続や生SQLの実行などを担当している。

DBIxDBI と連携してデータベースに色々な命令を発行するが、 DBI ではなく少し便利な DBI のサブクラスを定義して使うこともできる。

サブクラスを作って使う方法はドキュメントにも紹介されている。

たとえば DBIx::Sunny の実装を見ても、最初に use parent qw/DBI/; と書いてある。

実装したサブクラスを、元の DBI の代わりに使うには、RootClass 引数で指定する。

$dbh = DBI->connect(..., { RootClass => 'MySubDBI' });

MySubDBI->connect(...); と直接呼ぶのとの違いは、 もし MySubDBI クラスが存在しない場合ハンドリングがマイルドになっていることらしい。

参考