色々な検索方法3 #07B!

こんにちわ!nekokakです!

七日目はDBIx::Skinnyのresultsetメソッドについてです。

resultset

resultsetを使う事で、インクリメンタルに検索条件を設定することができます。

例えばCGIなどでユーザの入力を元に検索条件を組み立てる必要があることはよくあることでしょう。

そういう時にこのresultsetメソッドは大活躍できまうす。

DBIx::Skinnyでsearch_by_sql/search_namedの生SQLを書くケースをのぞいて

joinクエリが発行できるのもresultsetメドッドだけです。

今日はそんなresultsetメソッドに入門してみましょう。

まずresultsetのオブジェクトを作ります。

my $rs = $db->resultset;

次にselectするカラムを指定しましょう。

$rs->add_select('user.id' => 'user_id');

一つ目の引数はSELECT時に使用されるベースとなるカラム指定で

二つ目の引数はASで指定される名前になります

この場合、作られるSQLは

SELECT user.id AS user_id

となります。

selectするカラムはresultsetオブジェクトを作る時に指定する事も可能です。

my $rs = $db->resultset(
    {
        select => [
                    'user.id AS user_id',
                  ],
    }
);

resultsetでSQLを組み立てている時に途中でSQLを確認したくなる場合がありますが、その場合は

print $rs->as_sql;

とすればその時点で、どのようなSQLが組み上がるかが出力されます。

printデバッグ最高ですね!

次にselectするテーブルを指定します

# SELECT user.id AS user_id FROM user
$rs->from(['user']);

テーブルの指定は複数行う事も出来ます

# SELECT user.id AS user_id FROM user, profile
$rs->from(['user', 'profile']);

fromもresultsetオブジェクトを生成するタイミングで指定する事が可能です

my $rs = $db->resultset(
    {
        select => [
                    'user.id AS user_id',
                  ],
        from   => ['user'],
    }
);

次に検索条件を追加しましょう。

# SELECT user.id AS user_id FROM user WHERE user.name = ?
# bind: nekokak
$rs->add_where('user.name' => 'nekokak');

このようにadd_whereメソッドを使用して検索条件を追加していきます。

bindされた値を確認するには、

use Data::Dumper;
print Dumper $rs->bind;

printデバッグ最高ですね!

さて、この時点のSQLを発行したい場合はretrieveメソッドを使用します。

my $itr = $rs->retrieve;

retrieveメソッドを呼び出せば、今までくみ上げてきたSQLを使用して、DBに対して実行します。

retrieve呼び出し後の使い方は他のsearch系メソッドと同様です。

さらに複雑なSQLを組上げる

IN/NOT INを使う場合

$rs->add_where('user.id' => {'IN' => \@user_ids});
$rs->add_where('user.id' => {'NOT IN' => \@user_ids});

INの場合はこのように指定する事も可能です。

$rs->add_where('user.id' => \@user_ids);

比較演算子を使う場合

$rs->add_where('user.id' => {'<' => 1});
$rs->add_where('user.id' => {'>' => 1});
$rs->add_where('user.id' => {'!=' => 1});

IS NULL/ IS NOT NULLを指定したい場合はscalarリファレンスを指定します

$rs->add_where('user.id' => \'IS NULL');
$rs->add_where('user.id' => \'IS NOT NULL');

検索条件をorで囲みたい場合はこのように指定します

$rs->add_where('user.id' => [{'>' => 10}, {'<' => 100}]);

また検索条件を明示的にandで囲みたい場合は

$rs->add_where('user.id' => ['-and' => {'>' => 10}, {'<' => 100}]);

このように指定します。

また演算子が固定の場合は

$rs->add_where('user.id' => ['-and' => 1,2,3]);

このように指定する事も可能です。

テーブルJOINする場合

# FROM user INNER JOIN bookmark ON user.id = bookmark.user_id
$rs->from([]);
$rs->add_join(
    user => [
        {
            type  => 'inner',
            table => 'bookmark',
            condition => 'user.id = bookmark.user_id',
        },
    ],
);

このようなJOINクエリが生成されます。

始めに$rs->from([]);を呼び出して、from を空にしているのは

add_joinで起点となるテーブルを指定しているためです。

引数の

  • typeはjoinのさせ方
  • tableはjoinさせるテーブル
  • conditionはJOIN時の条件

となります。

これでDBIx::Skinnyの検索系メソッドは終了です。

明日は更新系メソッドの使い方を見ていきたいと思います。

have a nice skinny days!:)