Class::DBI::SweetでのJOIN
Class::DBI::Sweetのjoinをつかった検索を試してみた。
ソースコードは作っているアプリケーションからの抜きだしなので足りないところがあるかも。
EntryとそのTagを想定して、
package Entries; __PACKAGE__->table('entries'); __PACKAGE__->columns(All=>qw/id title text created_on/); __PACKAGE__->has_many("tags"=>'Tags'); 1; package Tags; __PACKAGE__->table('tags'); __PACKAGE__->columns(All=>qw/id entry_id tag/); __PACKAGE__->has_a('entry_id'=>'Entries'); 1;
の2つのクラスを作成。
例えば、「Perl」というTagを含むEntryがあるとして、それを検索するには
my ($pager,$entries) = Entries->page({ 'tags.tag'=>'perl' },{ rows=>10,page=>1, order_by=>'created_on desc' });
というのでOK。「tags.tag」でjoinを指定できます。「tags」の部分はテーブル名ではなくhas_manyで指定したリレーション名です。
このときに発行されるSQLは
SELECT me.id, me.title, me.text, me.created_on FROM entries me, tags tags WHERE ( tags.tag = 'Perl' ) AND me.id = tags.entry_id ORDER BY created_on desc LIMIT 0, 10
このようになっている。
ちなみにどんなSQLが発行されているか確認する為には、環境変数DBI_TRACEを2にすればいいらしい。Class::DBIのwikiに書いてありました。
$ENV{DBI_TRACE}=2;
とどっかに書くとトレースされます。出力される情報は結構多いです。
DBIx::Classはこの辺(joinの周り)がちょっと異なっていてよくまだわからない。
コメント
こんばんは。
DBIx::ClassでのSQLトレースですが、例えば、、、
DBI->trace(2 => "./logfile");
でlogfileに出力されます。
Class::DBIのwikiに書いてあるのも、結局はDBI自体のトレースを使ってます。
問題は、SQLが長くなった場合、全てのSQLをこの手法では拾えないところですね。これ、業務では結構痛いです。
投稿者: nekokak | 2005年12月07日 22:36
最後の文章はのかかる部分は全体のつもりだったのですが、いつもながらわかりにくい文章ですね。すみません。
DBIx::Classのログは
$ENV{DBIX_CLASS_STORAGE_DBI_DEBUG}=1;
これでもいけます。warningに出力ですけど。
DBIはDBIなんでDBI->trace(2 => "./logfile");も使えますね。
投稿者: かぜぶろ | 2005年12月07日 22:56