DBIx::Custom - SQLの実行が簡単なPerlのO/Rマッパー

モデルの作成

DBIx::Customで「モデル」を使う方法を解説します。モデルを作成すると、テーブルのフィールド情報を自動取得し活用できたり、join句を定義しておくことができます。

モデルを生成する - create_model

モデルを作成するにはcreate_modelメソッドを使用します。

# テーブル名を指定してモデルを作成
$dbi->create_model('book');

# テーブル名とjoin句を指定してモデルを作成
$dbi->create_model(
  table => 'book',
  join => [
    'left join company on book.company_id = company.id',
    'left join author on book.author_id = author.id',
  ],
);

create_modelの引数ではtableでテーブル名、joinでjoin句を指定することができます。joinには、複数のjoin句を指定することもできます。

このサンプルでは、joinでは、会社テーブルと著者テーブルを結合しています。

モデルの取得

作成したモデルはmodelメソッドでテーブル名を指定して取得することができます。

my $book = $dbi->model('book');

モデルを作成すると、DBIx::Custom::Modelが持つメソッドinsert, update,delete,selectなどを呼び出すことができます。

# insert
$dbi->model('book')->insert({id => 1, title => 'Perl'});

# uppdate
$dbi->model('book')->update({title => 'Perl'}, where => {id => 1});

# uppdate_all
$dbi->model('book')->update_all({title => 'Perl'});

# delete
$dbi->model('book')->delete(where => {id => 1});

# delete_all
$dbi->model('book')->delete_all;

# select
my $rows = $dbi->model('book')->select(where => {id => 1})->all;

join句とフィールド名の取得の組み合わせ

モデルを利用するとフィールド名を自動的に取得することができます。たとえば、bookテーブルにcompanyテーブルをjoinで結合して情報を取得する場合です。

たとえば、以下の場合を考えましょう。以下の例では、bookテーブルのすべてのフィールドを取得するSQLが実行されています。パラメーターはプレースホルダーに置き換えられます。

# すべての列を取得
# select * from book where id = ?
my $rows = $dbi->model('book')->select(where => {id => 1})->all;

さてここから、会社名を追加で取得したい場合です。このような場合に、モデルを定義しておくと、簡単に書けます。bookの列はすべて取得し、会社名を追加します。

# すべての列を取得
# select book.id as `id`, book.name as `name`, book.company_id as `company_id`, company.name as `company.name` 
#   from book left join company on book.company_id = company.id
#   where id = ?
my $rows = $dbi->model('book')->select(
  [
    {__MY__ => '*'},
    {company => ['name']}
  ],
  where => {id => 1}
)->all;

「__MY__」というテーブル名は、自分自身のテーブル名を意味し、テーブル名のプレフィックスなしの名前を取得してくれます。「*」ですべてのフィールドを取得することができます。

必要なjoin句が自動的に選ばれます。companyテーブルは結合されて、authorテーブルは、結合されません。

実際に実行されるSQLを眺めてみると、理解しやすいと思います。

bookというテーブルプレフィックスをつけて、フィールド名を指定することもできます。

# すべての列を取得
# select book.id as `book.id`, book.name as `book.name`, company.name as `company.name` 
#   from book left join company on book.company_id = company.id
#   where id = ?
my $rows = $dbi->model('book')->select(
  [
    {book => ['id', 'name']},
    {company => ['name']}
  ],
  where => {id => 1}
)->all;

モデルを作成すると、テーブルを結合して、フィールドを取得するということが、短い記述で行えます。