Idiormとは
PDOをそのまま使って業務システムを組んでいたのですが、大きくなるにつれてツラくなってきたので、ラッパーライブラリを探すことにしました。
以前はDoctrineを使っていたのですが、今の業務で使うには高機能すぎる感じがしたので、薄いライブラリを探していたところ、Idiormというのが良さそうだったので試してみることにしました。
$user = ORM::for_table('user')
->where_equal('username', 'j4mie')
->find_one();
$user->first_name = 'Jamie';
$user->save();
$tweets = ORM::for_table('tweet')
->select('tweet.*')
->join('user', array(
'user.id', '=', 'tweet.user_id'
))
->where_equal('user.username', 'j4mie')
->find_many();
foreach ($tweets as $tweet) {
echo $tweet->text;
}
http://j4mie.github.io/idiormandparis/
このソースは上記公式サイトの例ですが、なんとなくやっていることが分かると思います。
ドキュメント
http://idiorm.readthedocs.org/en/latest/index.html
こちらを見ればほぼすべての使い方が分かります。
インストール
https://github.com/j4mie/idiorm
こちらからダウンロードしてidiorm.phpを置いてrequireするだけです。1ファイルしか使わないので楽です。
Composerならば、
composer require j4mie/idiorm
でOKです。
デモ
demo.phpを開くとシンプルなコンタクトリストのデモが走ります。
SQLiteを使っていてテーブルも自動作成なので、何も用意する必要はありません。
使い方
基本的には静的メソッドfor_tableでテーブル名を指定するとORMオブジェクトが返ってくるので、それに対してメソッドをチェーンして行く感じです。
メソッド名
メソッド名はスネークケースとキャメルケースの両方に対応しています。例えばテーブルを指定するメソッドは「for_table」でも「forTable」でもOKという感じです。
※ただし、PHP 5.2ではキャメルケースでは動きませんでした。
カラムの指定
カラムを指定するときにはselectメソッドを使います。省略すると全カラムを取得します。
$users = ORM::for_table('user')
->select('name')
->find_many();
別名は第2引数で指定します。例えば「SELECT super_long_name AS name FROM user」の場合は、
$users = ORM::for_table('user')
->select('super_long_name', 'name')
->find_many();
複数カラムの場合は、チェーンを繋げるか、
$users = ORM::for_table('user')
->select('name')
->select('age')
->find_many();
select_manyを使います。
$users = ORM::for_table('user')
->select_many('name', 'age')
->find_many();
キモくないJOIN
一番上に提示した公式サイトのソースはJOINがキモイです。
->join('user', array(
'user.id', '=', 'tweet.user_id'
))
ですが、キモくない書き方もできます。やった!
->join('user', 'user.id = tweet.user_id')
ただし、エスケープされないので取り扱い注意。JOIN自体が嫌なら同じ作者の作ったActive Record実装であるParisを使うと良いです。
複数のレコードを配列で取得する
内部ではほとんどORMオブジェクトで操作しますが、JSONで出力したいときなど、配列が欲しいときはfind_arrayを使います。
$users = ORM::for_table('user')
->order_by_asc('id')
->find_array();
$json = json_encode($users);
1レコードを配列で取得する
1レコードの返り値をそのまま連想配列で返すメソッドがありません(たぶん)。なので、find_oneで1レコードをORMオブジェクトで返して、as_arrayで配列に変換します。
$user = ORM::for_table('user')
->where('id', $id)
->find_one()
->as_array();
補足:カラム名がidなら以下のような省略記法も使えるようです。
$user = ORM::for_table('user')
->find_one($id)
->as_array();
複数レコードを同時に操作する
find_result_setを使うと複数レコードを同時に操作出来ます。
例:カラムnameが「太郎」のレコードを全て「花子」にする場合
$user = ORM::for_table('user')
->where('name', '太郎')
->find_result_set()
->set('name', '花子')
->save();
連想配列からの挿入・更新
連想配列にレコードの値が入っていて、テーブルにそのidのレコードがあればupdate、なければinsertという処理は以下のように書きました。
$in = [
'id' => 4,
'name' => '山田'
];
$user = ORM::for_table('user')->find_one($in['id']);
if (!$user) $user = ORM::for_table('user')->create();
$user->set($in);
$user->save();
レコードがなければcreateメソッドで新規作成しています。
最後に挿入されたレコードの連番値を取得
ID列が連番(AUTO_INCREMENT)のときに、挿入されたID値を取得したい場合はLAST_INSERT_ID()
を使っても構いませんが、idメソッドを使うと簡単に取れます。
$user = ORM::for_table('user')->create();
$user->set($in);
$user->save();
$id = $user->id();
キャッシュ
ORM::configure('caching', true);
キャッシュが有効になり、同じSELECT文を発行した場合は、結果をメモリキャッシュから取得するようになります。
ORM::configure('caching_auto_clear', true);
INSERTやUPDATEでキャッシュをクリアします。
副作用はほとんど無いと思われますので、常にこの2行を設定しておくと良いでしょう。
注意点
複合主キーには対応していません。
これに気づかず急いでサロゲートキーを作った次第です。主キーの名前はデフォルトで「id」ですが、configメソッドでテーブルごとに変更することもできます。