PerlのO/Rマッパーよくある機能一覧
こんにちは!hirobanexです!Casualなぼくなんで、Casual向けに、生DBIじゃなくてDBIx系が出てくる理由とか、O/Rマッパーでできることとか、そんな感じのふわっとしたところを考えてまとめてみたいと思います。
サマリ
ざっくりまとめると、O/Rマッパーの機能一覧(=DBIで扱いづらい一覧)は以下のようになります。
- トランザクション管理
- Fork管理
- コネクション管理
- 警告/エラー設定
- Perl内部文字列化設定
- トリガー
- クエリビルディング
- インフレイト/デフレイト
- リレーション設定
さて、それぞれCasualに解説していきたいと思います。
トランザクション管理
DBIを生で使って、autocommitオプションから、beginとかcommitとかrollbackしたりしてもいいですが、もっと簡単(気軽に)に使いたいと思いますよね?!例えば、小分けにしたメソッドをまとめて、全体でトランザクションかけるんだけど、小分けにしたメソッド個別でもトランザクションかけておきたいかいう場合ですね。O/Rマッパーでは良い感じに、ネストをサポートした、トランザクション開始を宣言から終了宣言までの間でコミットとロールバックしてくれるメソッドが提供されています!その他、詳しくは、[/articles/advent-calendar/2011/dbix/1:title=第一回のnekokakさんの『DBIx::Handlerで安心DB生活』]を御覧ください。
Fork管理
生のDBIを使ってParallel::ForkmanagerとかPrefork型のサーバーを使っていたりすると問題が発生することがあります。詳しくは、[/articles/advent-calendar/2011/dbix/4:title=第四回のnihenさんの『続DBIとforkの関係』]を御覧ください。
コネクション管理
DBIを生で使っていると、データベース側からいつの間にかコネクション切られてしまったり、[/articles/advent-calendar/2010/hacker/3:title=意図せずダラダラとコネクションが維持され続けたり]、悩ましいことが多いですね。とりあえず、トランザクションとかForkとかコネクションはわりと密結合な関係なので、O/RマッパーとかDBIx系のモジュールまかせるに越したことはありませんね!
警告/エラー設定
DBIには、RaiseErrorとかPrintErrorとか設定がありますが、最初はなんだかよくわかりませんね。なので、このあたりの設定もとりあえず、O/Rマッパーとか任せるいいですね。
Perl内部文字列化設定
外部の文字列はデコードしてからPerlで扱うのが一般的です。なので、DBから取得したデータもしたいのですが、いちいちselectするたびにデコードするのはしんどいですね!このあたりを良い感じに一括で行う設定はDBIだとデータベース別に違うので、これもO/Rマッパーに任せると楽ですね。
トリガー
insertする前/後、updateする前/後などに、実行した機能を実装できるのがトリガーです。データベース側でもトリガーがついていますが、プログラムベースでもトリガーがつけられると、コード側にロジックを確保できるのでうれしかったりします。
クエリビルディング
Perlのデータ構造でSQL文を表現することです。O/Rたる所以ですが、生SQLを書くのがしんどいことがありますね。クエリビルダーを使うと、ある程度リファレンスができているときに$db->search('user',$where)のように取得できたり、条件によって$whereを切り替えたりするのに非常に便利です。また、find_or_createとか$db->insert($table, \%record, 'INSERT IGNORE');みたいなショートカットメソッドもあったりますね。非常に開発しやすいですね!
インフレイト/デフレイト
SQLにの返り値の生データをPerlオブジェクトにするのがインフレイトで、PerlオブジェクトからSQLのデータ文字列にするのがデフレイトです。具体的には、「Perl内部文字列化設定」のように、Perlコード内では、日付データを生ではなくDateTimeのオブジェクトで持っていたかったり、Perlのデータ構造をSQL内ではJSONなどで保存しておきたかったり、というケースに利用できます。とてもうれしいですね!
リレーション設定
RDBMSでは、テーブル間でカラムを共有することがほとんどです。userテーブルのプライマリーキーのidが、tweetテーブルのキーになっていたり、テーブル間でいろんな関係が表現されていますが、O/Rマッパーでもその関係を描くことができます。意識して使えば便利ですね!詳しくは、こちらのtypesterさんの「リレーションの定義」の解説ご御覧ください。
【補足】Iteratorオブジェクト、Rowオブジェクト
O/Rマッパーとか使っていると、クエリのリターンバリューが、このようなオブジェクトになっていると思います。「なんかちょっとわかりづらいなー、小難しいなー」という気が最初はするのですが、このようなオブジェクトのカタチに実装することで、上述してきた機能を実装することが可能になりますし、その他の便利な機能を実装されているので、しっかりO/Rマッパーのドキュメントやコード読んで使うといいですね。
最後に
「あれ?なんか人の記事から拝借しすぎじゃない?」という気もしますが、Casualな感じで許してもらえればです。なんとなくレベルでO/RマッパーやDBIx系モジュールを使う意味が理解できて頂ければ何よりです。煩雑になるので、具体的なO/Rマッパー名やモジュール名は列挙できませんでしたが、基本的にDBIx::ClassとかTengとかならだいたい実装されているようなので、是非それらを使ってみては如何でしょうか。まだ紹介されていない個別の機能だけに対応するようなDBIxモジュールに関しては、今後PerlHackerの方が紹介してくれると思います!
さて、次はkazeburoさんです。See you later!