DB以外でDBIx::Skinny::Iteratorを使う #15
こんにちわ!nekokakです!
十伍日目はDBIx::SkinnyでDB意外のデータを使う方法についてです。
DBIx::SkinnyはDBIxとついているように、DBIを拡張するモジュールです。
しかし、データのイテレーションはDBのデータ意外でも使いたい場合があると思います。
そこで、今日は、DBのデータ意外でのIteratorの使い方についてです。
と、その前に、DBIx::Skinny::Iteratorの使い方をざっくり説明しましょう。
DBIx::Skinny::IteratorはDB検索結果のレコードを取りまとめるオブジェクトとなります。
複数のレコードを取りまとめて、データをイテレーションさせるためのクラスです。
itaratorではnext/first/reset/count/allというメソッドがあります。
nextメソッドを使うと、1行ずつデータを取得して、処理を行うことができます。
my $itr = $db->search('user');
while (my $row = $itr->next) {
# some process....
}
allメソッドを使うと、一気に配列に行データを格納することができます。
my $itr = $db->search('user');
my @users = $itr->all;
firstメソッドを使うと、イテレータから1行だけデータを取得することができます。
my $itr = $db->search('user');
my $user = $itr->first;
countメソッドを使うと、現在イテレータが保持しているデータのレコード数を取得することができます。
my $itr = $db->search('user');
my $count = $itr->count;
resetメソッドを使うと、途中まで進めたイテレータのポジションをはじめに戻すことができます。
下の例の場合、resetメソッドを呼び出さないと、allメソッドでは2行目以降のデータしか取得できません。
my $itr = $db->search('user');
# 1行目を取得(イテレータのポジションが一個進む)
my $user = $itr->first;
# イテレータのポジションをリセットする
$itr->reset;
# 全行を取得する
my @users = $itr->all;
no_cacheメソッドというのがgithubの最新バージョンに存在します。
これはDBIx::Skinny::IteratorがDBから取り出した行データをインスタンスにキャッシュしているのをやめるものです。
resetメソッドを組み合わせて、同じSQLの実行結果を使いまわす場合は、
インスタンスにキャッシュされたデータをつかいまわすと、DBに余計なクエリを発行擦る必要がなく、
負荷軽減になるのですが、同じSQLの実行結果を使いまわさない場合で、
1クエリで大量のレコードが取得される場合、インスタンスにキャッシュしてしまうと
メモリの無駄遣いになるので、そういった場合に使用します。
my $itr = $db->search('user');
# itratorインスタンスにrowデータをキャッシュしないことを指示
$itr->no_cache;
my @users = $itr->all;
DBIx::Skinny::Itaratorの使い方としてはこんな感じです。
DBIx::Classを普段使っている人は特に違和感なく使えると思います。
さて、本日の本題である、DB意外のデータをDBIx::Skinny::Itaratorで扱う方法ですが、
例えば、
my @users = (
{name => 'nekokak'},
{name => 'yappo'},
{name => 'nekoya'},
);
my $itr = Proj::DB->data2itr('user', \@users);
while (my $row = $itr->next) {
warn $row->name;
}
このような使い方が可能です。
data2itrメソッドを使うと、ある、hashrefが格納されてるarrayrefをわたすと、
DBIx::Skinny::Iteratorのオブジェクトにしてくれます。
#14で説明した、memcachedから取得したデータをitaratorに戻すのと同じです。
itaratorに戻した後に取得される1データはDBIx::SkinnyのRowクラスでオブジェクト化されていますので、
あたかもDBから取得したデータのように扱うことが可能です。
本題がめっちゃ短いですが、simple is bestということで。
明日はDBIx::Skinnyを使った場合のdb shardingについて書いてみようかと思います。
have a nice skinny days!:)