Catalyst::Model::DBIC::Schemaでselect,insert,updateとかのメモ
※事前にTestDB::Memberに対応する
membersテーブルが作成されていること。
事前の設定などは前回の記事のModel部分を参照。
http://d.hatena.ne.jp/oggata/20110420/1303291384
キーによる検索
sub find :Local{ my $mdata = $c->model('TestDB::Member')->find(1); my $name = $mdata->name; }
カラムを条件とした検索
sub findByKey :Local{ $c->stash->{TestTable} = $c->model('TestDB::Member')->find{'AAAA',{key=>'title'}} }
結果をリストに表示する
=pod <a>[%- TestTable.name|html -%]</a> <a>[%- TestTable.price|html -%]</a> <a>[%- TestTable.amount|html -%]</a> <a>[%- TestTable.comment|html -%]</a> =cut
大なり小なりを使った条件
sub where :Local{ my $mdata = [$c->model('CatalDB::Member')->search({insert_time=>{'>'=>'2012-01-01'}})]; my $name = $mdata->first->name; }
複数カラムのAND条件
#and sub where :Local{ $c->stash->{TestTable} = [$c->model('TestDB::Member')->seaerch({title=>'AAAA',insert_time=>{'>'=>'2012-05-01'}})]; }
複数カラムのOR条件
#or sub where :Local{ $c->stash->{TestTable} = [$c->model('TestDB::Member')->search({title=>'AAAA'},{insert_time=>{'>'=>'2012-01-01'}})]; }
並び替え
#order by sub orderby :Local{ $c->stash->{list} = [$c->model('TestDB::Member')->search({},{order_by => {-desc => 'insert_time','title'}})]; }
カウントの取り方
sub count :Local{ my($self,$c)=@_; my $result = $c->model('Catal::DB')->search({publish => 'aaaa'})->count; $c->response->body("${result}件が検索されました。"); $c->stash->{template}='aa.tt'; }
ページャーの作り方
sub rows :LOcal{ my($self,$c,$page)=@_; $page = 1 unless $page; $c->stash->{list}=[$c->model('Catal::DB')->search(undef,{order_by=>{-desc=>['published','price']},rows=>3,page=>$page})]; $c->stash->{template}='aa.tt'; }
search_literalメソッドの使い方
sub search_literal :Local{ my ($self,$c)=@_; $c->stash->{list} = [$c->model('Catal::Book') ->search_literal('(title like ? or published > ?) and pubish = ?',('%Perl%','2009-01-01','AAAA'))]; }
レコードの登録、更新
レコードの登録
#レコードの登録 sub insert :Local{ my($self,$c) = @_; my $row = $c->model('TestDB::Member')->create({ id => 1, title => 'AAA', price => 1000, insert_date => \'NOW()' }); $c->response->body('登録完了'); }
#レコードの登録2 sub insert2 :Local{ my($self,$c) = @_; my $row = $c->model('TestDB::Member')->new({}); $row->id(1); $row->title('AAA'); $row->price(1000); $row->insert_date(\'NOW()'); $row->insert(); }
レコードの更新
#データの更新 sub update :Local{ my($self,$c)=@_; my $row = $c->model('TestDB::Member')->find('1'); $row->title('BBB'); $row->price(1200); $row->update(); $c->response->body('更新完了'); }
レコードがなければInsert
#find_or_new sub find_or_new :Local{ my($self,$c)=@_; my $TestTable = $c->model('TestDB::Member')->find_or_new({ id => 1, title => 'CCC', price => 1000, insert_date => '2012-05-01' }); if($TestTable->in_storage){ $c->response->body('既にデータが存在します'); }else{ $TestTable->insert(); $c->response->body('登録しました'); } }
レコードがあればUpdate、無ければInsert
#update_or_new sub update_or_new :Local{ my($self,$c)=@_; my $review = $c->model('TestDB::Member')->update_or_new({ id => 1, title => 'aaaa', price => 100, insert_date = '2012-01-01' }); if($review->in_storage){ $c->response->body('update完了'); }else{ $review->insert(); $c->response->body('insert完了'); } }
トランザクション
トランザクションの使い方
#transaction(DBIx::ClassSchemaクラスのtxn_doメソッド) sub transaction :Local{ my($self,$c)=@_; eval{ $c->model('TestDB')->schema->txn_do(sub{ $c->modle('TestDB::Member')->create({ id => 1, title => 'AAAA' }); $c->model('TestDB::Member')->create({ id => 1, title => 'AAAA' }); }); }; if($@){ if($@ =~ /rollback failed/ ){ $c->response->body('ロールバック失敗'); }else{ $c->response->body('ロールバック完了'); } return; } $c->response->body('トランザクション成功'); }
ActionとModelの分離
#Actionとmodelの分離 Catalyst::ModelLLAdaptorを使用する #アダプターの作成 _create.pl model モデル名 Adaptor モデル化するクラス名 コンストラクタ名 catal_create.pl model MemberAdaptor Adaptor Catal::Api::Member new use Catal::Api::Member; #削除 sub adaptor :Local{ my ($self,$c) = @_; my $TestTable = $c->model('MemberAdaptor'); $c->stash->{list} = $TestTable->getInfosByPublish('テストだよ'); $c->stash->{template}->'list.tt'; }