#06 search_by_sql / search_named

2011-12-06

今日はTengをつかったデータの取得方法の続きになります。

search_by_sql

Tengではsingleメソッドなどを使うと自分でSELECT文を書く必要が無く、
内部でクエリを自動生成し、databaseに問い合わせをおこないますが、
複雑なクエリ担ってきた場合、クエリビルダーをつかってSQLを生成すると問題が発生することがあります。

JOINするようなクエリをクエリビルダで生成する場合、
実際のPerlのロジックからどういうSQLが生成されるかを考えるのが以外に面倒だったりします。

まぁちょっと込み入ったクエリを発行したい場合は生のSQLを使うのが一番だと懐います。

そういった場合にTengではsearch_by_sqlメソッドを利用します。

my $itr = $teng->search_by_sql('select * from user where id = ?', [qw/1/]);

search_by_sqlの返却値はTeng::Iteratorのオブジェクトとなっていますので
イテレータ経由でRowオブジェクトを取得し、データにアクセスすることになります。

イテレータの使い方についての詳細は明日説明します。

search_by_sqlではJOINしたクエリを実行することがあると思います。
その場合複数テーブルにまたがったクエリになることがおおく、イテレータから取得されるRowオブジェクトを
どのtableに紐付けるかがむずかしくなります。

その場合search_by_sqlの第三引数にRowオブジェクトに紐付けしたいtable名を指定することで解決できます。

my $itr = $teng->search_by_sql('SELECT * FROM user WHERE id = ?', [qw/1/], 'user');

今回の例のような単純なSELECTクエリの場合は、Tengが自動で対応付けるtableをみつけだすので
特別指定する必要はありません。

なぜRowオブジェクトに対応するtableを指定する必要があるかは後日説明します。

search_named

search_by_sqlでは

my $itr = $teng->search_by_sql('SELECT * FROM user WHERE id = ?', [qw/1/]);

プレスホルダーとして?を指定することになりますが、?での指定だとbindする値の順番を厳密に守る必要があります。
また同じ値をbindの値として指定したい場合にも若干面倒なのでそういった場合にsearch_namedメソッドを利用するとよいでしょう。

my $itr = $teng->search_named('SELECT * FROM user WHERE id = :user_id', +{user_id => 1});

search_namedメソッドを利用すればプレスホルダーの指定の部分を?ではなく:{key_name}として指定します。
この場合は:user_idですね。
これに対応するhashrefを第二引数で指定してあげればあとはTengが自動的に?に置き換え、bindの値も生成してくれます。

search_namedの第三引数にはsearch_by_sqlと同じようにRowオブジェクトに対応するtable名を指定することができます。


複雑なSQLはsearch_by_sqlやsearch_namedメソッドを利用すればいいのですが、
単純なSQLの発行に毎回SQLかいてられっか!ってこともあるのでそういう場合はsearchメソッドをつかうとよいでしょう。
searchメソッドは後日説明します。


明日はイテレータについての説明をしたいと思います