added experimental expand me...
|
1 |
=encoding utf8 |
2 | ||
updated document
|
3 |
=head1 NAME |
added experimental expand me...
|
4 | |
update pod
|
5 |
DBIx::Custom::Guide::Ja - DBIx::Customのガイドブック |
added experimental expand me...
|
6 | |
7 |
=head1 ガイド |
|
8 | ||
update pod
|
9 |
L<DBIx::Custom>はSQLの実行を簡単に行うためのクラスです。 |
10 |
L<DBIx::Class>やL<DBIx::Simple>と同じように |
|
updated document
|
11 |
L<DBI>のラッパクラスになっています。L<DBIx::Class>よりも簡単に、 |
12 |
L<DBIx::Simple>よりもはるかに柔軟なことを行うことができます。 |
|
added experimental expand me...
|
13 | |
14 |
L<DBIx::Custom>はO/Rマッパーではありません。O/Rマッパーは |
|
15 |
便利ですが、O/Rマッパのたくさんの文法を覚える必要があります。 |
|
updated document
|
16 |
また、O/Rマッパによって生成されたSQLは非効率なことがありますし、 |
17 |
複雑なSQLを生成することができないので、 |
|
update pod
|
18 |
生のSQLを実行しなければならない場合がたくさんあります。 |
added experimental expand me...
|
19 | |
updated document
|
20 |
L<DBIx::Custom>はO/Rマッパとは対照的な設計が行われています。 |
updated document
|
21 |
L<DBIx::Custom>の主な目的は、SQLを尊重しつつ、L<DBI>だけでは |
updated document
|
22 |
とてもめんどうな作業を簡単にすることです。もしSQLについて |
23 |
多くの知識を持っているならば、L<DBIx::Custom>でそのまま |
|
updated document
|
24 |
活用することができます。 |
updated document
|
25 | |
update pod
|
26 |
L<DBIx::Custom>の仕組みを少しだけ説明しておきます。 |
updated pod
|
27 |
L<DBIx::Custom>では、パラメーターと呼ばれるものを |
updated document
|
28 |
SQLの中に埋め込むことができます。 |
29 | ||
updated pod
|
30 |
select * from book where title = :title and author = :author; |
updated document
|
31 | |
updated pod
|
32 |
:titleや:authorがパラメーターです。このSQLは実際に実行されるときには |
updated document
|
33 |
次のようにプレースホルダに展開されます。 |
34 | ||
updated document
|
35 |
select * from book where title = ? and author = ?; |
updated document
|
36 | |
37 |
これらの展開にはどのような意味があるのでしょうかと質問 |
|
update pod
|
38 |
されるかもしれません。この簡単な仕組みの上に |
39 |
便利な機能が実装されます。それは以下のようなものです。 |
|
updated document
|
40 | |
updated document
|
41 |
=over 4 |
updated document
|
42 | |
update pod
|
43 |
=item 1. プレースホルダにバインドする値をハッシュリファレンスで指定 |
updated document
|
44 | |
update pod
|
45 |
L<DBI>を使うのであればプレースホルダにバインドする値は配列 |
updated document
|
46 |
で指定する必要があります。 |
updated document
|
47 | |
updated document
|
48 |
$sth->execute(@bind); |
49 | ||
50 |
L<DBIx::Custom>を利用するのであればハッシュリファレンスで指定すること |
|
51 |
できます。 |
|
52 |
|
|
53 |
my $param = {title => 'Perl', author => 'Ken'}; |
|
54 |
$dbi->execute($sql, $param); |
|
55 | ||
update pod
|
56 |
=item 2. 値のフィルタリング |
updated document
|
57 | |
update pod
|
58 |
L<DBIx::Custom>はフィルタリングの機能を提供します。 |
updated document
|
59 |
たとえば、日付の列は、Perlで扱うときにはC<Time::Piece>などの日付オブジェクト |
60 |
で扱い、データベースに格納するときはデータベースの日付型に変換したい |
|
61 |
と思うのではないでしょうか。またデータベースから取り出すときは |
|
62 |
データベースの日付型から日付オブジェクトに変換したと思うのでは |
|
63 |
ないでしょうか。 |
|
64 | ||
65 |
このようなときはフィルタ機能を使うことができます。 |
|
66 | ||
67 |
まずフィルタを登録します。 |
|
68 | ||
69 |
$dbi->register_filter( |
|
70 |
tp_to_date => sub { |
|
71 |
... |
|
72 |
}, |
|
73 |
date_to_tp => sub { |
|
74 |
... |
|
75 |
} |
|
76 |
); |
|
77 | ||
78 |
次にテーブルの各列にこのフィルタを適用します。 |
|
79 | ||
80 |
$dbi->apply_filter('book', |
|
renamed dbi_options to dbi_o...
|
81 |
'issue_date' => {out => 'tp_to_date', in => 'date_to_tp'} |
updated document
|
82 |
); |
83 | ||
84 |
outはPerlからデータベースに保存する方向、inはデータベースからPerlに取得する方向です。 |
|
85 | ||
update pod
|
86 |
多くのメソッドで自動的にこのフィルタが有効になります。 |
updated document
|
87 | |
update pod
|
88 |
$dbi->insert(table => 'book', param => {issue_date => $tp}); |
updated document
|
89 | |
90 |
=item 3. 選択的な検索条件 |
|
91 | ||
update pod
|
92 |
L<DBI>では選択的に検索条件を作成することは難しいです。 |
updated document
|
93 | |
94 |
たとえば、検索条件にtitleとauthorが指定された場合は次のSQLを |
|
95 | ||
96 |
select * from book where title = ? and author = ?; |
|
97 | ||
98 |
titleだけの場合は次のSQLを |
|
99 | ||
100 |
select * from book where title = ?; |
|
101 |
|
|
update pod
|
102 |
authorだけの場合は次のSQLを実行した場合を考えましょう。 |
updated document
|
103 | |
104 |
select * from book where author = ?; |
|
105 | ||
106 |
これはとても大変な作業なので、通常はL<SQL::Abstract>を動的に生成してくれる |
|
107 |
モジュールを利用することになります。 |
|
108 | ||
109 |
L<DBIx::Custom>はさらに簡単で便利な方法を用意しています。 |
|
110 | ||
update pod
|
111 |
# Whereオブジェクト |
updated document
|
112 |
my $where = $dbi->where; |
update pod
|
113 |
|
114 |
# 検索条件 |
|
updated document
|
115 |
$where->clause( |
updated pod
|
116 |
['and', 'title = :title', 'author = :author'] |
updated document
|
117 |
); |
update pod
|
118 |
|
119 |
# 必要な列を自動的に選択するための設定 |
|
120 |
$where->param({title => 'Perl'}); |
|
updated document
|
121 | |
update pod
|
122 |
# SQLへのWhere句の埋め込み |
updated document
|
123 |
my $sql = "select * from book $where"; |
124 | ||
125 |
詳しい説明は後ほど行いますが、上記のように記述すれば、 |
|
126 |
L<DBIx::Custom>では選択的な検索条件を持つWhere句を生成することができます。 |
|
127 |
検索条件が入れ子になった構造やorについても対応しています。 |
|
128 | ||
129 |
=item 4. 挿入、更新、削除、選択を行うためのメソッド |
|
130 | ||
update pod
|
131 |
L<DBIx::Custom>では挿入、更新、削除、選択を行うための |
132 |
メソッドを提供しています。 |
|
133 |
C<insert()>, C<update()>, C<delete()>,C<select()>などがあります。 |
|
updated document
|
134 | |
135 |
my $param = {title => 'Perl', author => 'Ken'}; |
|
136 |
$dbi->insert(table => 'book', param => $param); |
|
137 | ||
update pod
|
138 |
=item 5. テーブルのためのメソッドの登録 |
updated document
|
139 | |
update pod
|
140 |
テーブルのためにメソッドを登録することができます。 |
updated document
|
141 | |
update pod
|
142 |
$dbi->table('book')->method( |
updated document
|
143 |
list => sub { |
144 |
... |
|
145 |
}, |
|
update pod
|
146 |
something => sub { |
147 |
... |
|
updated document
|
148 |
} |
149 |
); |
|
150 | ||
update pod
|
151 |
メソッドの利用です。 |
updated document
|
152 | |
153 |
$dbi->table('book')->list; |
|
added experimental expand me...
|
154 | |
update pod
|
155 |
多くのO/Rマッパではテーブルのためのクラスを作成する必要がありますが、 |
156 |
L<DBIx::Custom>では簡単です。 |
|
added experimental expand me...
|
157 | |
updated document
|
158 |
=back |
159 | ||
update pod
|
160 |
L<DBIx::Custom>はとても便利です。 |
161 |
興味をもたれた方は、続きをご覧になってみてください。 |
|
added experimental expand me...
|
162 | |
163 |
=head2 1. データベースへの接続 |
|
164 | ||
update pod
|
165 |
L<DBIx::Custom>を読み込みます。 |
updated document
|
166 | |
167 |
use DBIx::Custom; |
|
168 | ||
update pod
|
169 |
データベースに接続するにはC<connect()>メソッドを使用します。 |
170 |
戻り値はL<DBIx::Custom>オブジェクトです。 |
|
added experimental expand me...
|
171 | |
updated document
|
172 |
my $dbi = DBIx::Custom->connect( |
data_source is DEPRECATED! I...
|
173 |
dsn => "dbi:mysql:database=bookstore", |
updated document
|
174 |
user => 'ken', |
175 |
password => '!LFKD%$&', |
|
176 |
dbi_options => {mysql_enable_utf8 => 1} |
|
177 |
); |
|
added experimental expand me...
|
178 | |
data_source is DEPRECATED! I...
|
179 |
C<dsn>はデータベースシステムに応じたものである必要があります。 |
update pod
|
180 |
以下はデータソースのサンプルです。 |
added experimental expand me...
|
181 | |
updated document
|
182 |
B<MySQL> |
added experimental expand me...
|
183 | |
deprecated DBIx::Custom::MyS...
|
184 |
"dbi:mysql:database=$database" |
185 |
"dbi:mysql:database=$database;host=$hostname;port=$port" |
|
added experimental expand me...
|
186 | |
updated document
|
187 |
B<SQLite> |
deprecated DBIx::Custom::MyS...
|
188 | |
189 |
"dbi:SQLite:dbname=$database" |
|
190 |
"dbi:SQLite:dbname=:memory:" |
|
191 | ||
updated document
|
192 |
B<PostgreSQL> |
deprecated DBIx::Custom::MyS...
|
193 | |
194 |
"dbi:Pg:dbname=$dbname" |
|
195 | ||
updated document
|
196 |
B<Oracle> |
deprecated DBIx::Custom::MyS...
|
197 | |
198 |
"dbi:Oracle:$dbname" |
|
199 |
"dbi:Oracle:host=$host;sid=$sid" |
|
200 | ||
updated document
|
201 |
B<ODBC(Microsoft Access)> |
deprecated DBIx::Custom::MyS...
|
202 | |
203 |
"dbi:ODBC:driver=Microsoft Access Driver (*.mdb);dbq=hoge.mdb" |
|
204 | ||
updated document
|
205 |
B<ODBC(SQL Server)> |
deprecated DBIx::Custom::MyS...
|
206 | |
207 |
"dbi:ODBC:driver={SQL Server};Server=(local);database=test;Trusted_Connection=yes;AutoTranslate=No;" |
|
added experimental expand me...
|
208 | |
update pod
|
209 |
認証が必要な場合は、C<user>とC<password>を指定できます。 |
updated document
|
210 | |
update pod
|
211 |
L<DBIx::Custom>はL<DBI>のラッパークラスです。 |
212 |
L<DBI>のデータベースハンドルは取得するにあhC<dbh()>を使用します。 |
|
added experimental expand me...
|
213 | |
214 |
my $dbh = $dbi->dbh; |
|
215 | ||
updated document
|
216 |
L<DBIx::Custom>ではデータベースハンドル属性にはデフォルトで次のものが設定されます。 |
added experimental expand me...
|
217 |
|
218 |
$dbi->dbh->{RaiseError} = 1; |
|
219 |
$dbi->dbh->{PrintError} = 0; |
|
220 |
$dbi->dbh->{AutoCommit} = 1; |
|
221 | ||
update pod
|
222 |
致命的なエラーが起こるとプログラムは終了します。 |
223 |
SQLが実行されると自動的にコミットされます。 |
|
added experimental expand me...
|
224 | |
updated document
|
225 |
=head2 2. 挿入、更新、削除、選択のためのメソッド |
added experimental expand me...
|
226 | |
update pod
|
227 |
下記のメソッドがあります。 |
added experimental expand me...
|
228 | |
update pod
|
229 |
=head3 行の挿入 C<insert()> |
added experimental expand me...
|
230 | |
update pod
|
231 |
データベースに行を挿入するにはC<insert()>を使用します。 |
added experimental expand me...
|
232 | |
remove DBIx::Custom::Model
|
233 |
$dbi->insert(table => 'book', |
added experimental expand me...
|
234 |
param => {title => 'Perl', author => 'Ken'}); |
235 | ||
update pod
|
236 |
C<table>はテーブル名、C<param>は挿入する行のデータです。 |
added experimental expand me...
|
237 | |
update pod
|
238 |
次のSQLが実行されます。 |
updated document
|
239 | |
240 |
insert into (title, author) values (?, ?); |
|
added experimental expand me...
|
241 | |
update pod
|
242 |
=head3 データの更新 C<update()> |
added experimental expand me...
|
243 | |
update pod
|
244 |
データベースの行を更新するには、C<update()>を使用します。 |
added experimental expand me...
|
245 | |
remove DBIx::Custom::Model
|
246 |
$dbi->update(table => 'book', |
added experimental expand me...
|
247 |
param => {title => 'Perl', author => 'Ken'}, |
248 |
where => {id => 5}); |
|
249 | ||
update pod
|
250 |
C<table>はテーブル名、C<param>は更新データ、C<where>は |
251 |
条件です。 |
|
added experimental expand me...
|
252 | |
update pod
|
253 |
次のSQLが実行されます。 |
updated document
|
254 | |
255 |
update book set title = ?, author = ?; |
|
added experimental expand me...
|
256 | |
update pod
|
257 |
安全のためC<where>のないupdate()を実効することはできません。 |
added experimental expand me...
|
258 |
もしすべての行を更新したい場合は |
updated document
|
259 |
C<update_all()>を使用してください。 |
added experimental expand me...
|
260 | |
remove DBIx::Custom::Model
|
261 |
$dbi->update_all(table => 'book', |
added experimental expand me...
|
262 |
param => {title => 'Perl', author => 'Ken'}); |
263 | ||
update pod
|
264 |
=head3 データの削除 C<delete()> |
added experimental expand me...
|
265 | |
update pod
|
266 |
データベースの行を1件削除するには、C<delete()>を使用します。 |
added experimental expand me...
|
267 | |
remove DBIx::Custom::Model
|
268 |
$dbi->delete(table => 'book', |
added experimental expand me...
|
269 |
where => {author => 'Ken'}); |
270 | ||
update pod
|
271 |
C<table>はテーブル名、C<where>は条件です。 |
added experimental expand me...
|
272 | |
update pod
|
273 |
次のSQLが実行されます。 |
updated document
|
274 | |
275 |
delete from book where id = ?; |
|
added experimental expand me...
|
276 | |
update pod
|
277 |
安全のためC<where>のないC<delete()>を実効することはできません。 |
added experimental expand me...
|
278 |
もしすべての行を削除したい場合は |
updated document
|
279 |
C<delete_all()>を使用してください。 |
added experimental expand me...
|
280 | |
remove DBIx::Custom::Model
|
281 |
$dbi->delete_all(table => 'book'); |
added experimental expand me...
|
282 | |
update pod
|
283 |
=head3 データの選択 C<select()> |
added experimental expand me...
|
284 | |
updated document
|
285 |
行を選択するにはC<select()>を使用します。 |
added experimental expand me...
|
286 | |
remove DBIx::Custom::Model
|
287 |
my $result = $dbi->select(table => 'book'); |
added experimental expand me...
|
288 | |
update pod
|
289 |
次のSQLが実行されます。 |
added experimental expand me...
|
290 | |
updated document
|
291 |
select * from book; |
added experimental expand me...
|
292 | |
update pod
|
293 |
戻り値はL<DBIx::Custom::Result> |
updated document
|
294 |
オブジェクトです。行をフェッチするにはC<fetch()>を使用します。 |
added experimental expand me...
|
295 | |
296 |
while (my $row = $result->fetch) { |
|
297 |
my $title = $row->[0]; |
|
298 |
my $author = $row->[1]; |
|
299 |
} |
|
300 | ||
update pod
|
301 |
L<DBIx::Custom::Result>についてはL<3. 行のフェッチ/"3. 行のフェッチ">を見てください。 |
updated document
|
302 | |
update pod
|
303 |
サンプルを続けます。 |
added experimental expand me...
|
304 | |
305 |
my $result = $dbi->select( |
|
remove DBIx::Custom::Model
|
306 |
table => 'book', |
updated document
|
307 |
column => ['author', 'title'], |
added experimental expand me...
|
308 |
where => {author => 'Ken'} |
309 |
); |
|
310 | ||
update pod
|
311 |
C<column>は列名、C<where>は条件です。 |
312 | ||
313 |
次のSQLが実行されます。 |
|
updated document
|
314 | |
315 |
select author, title from book where author = ?; |
|
added experimental expand me...
|
316 | |
update pod
|
317 |
次のサンプルです。 |
added experimental expand me...
|
318 | |
319 |
my $result = $dbi->select( |
|
cleanup
|
320 |
table => 'book', |
321 |
column => ['company.name as company__name'] |
|
322 |
where => {'book.name' => 'Perl'}, |
|
323 |
join => ['left outer join company on book.company_id = company.id] |
|
added experimental expand me...
|
324 |
); |
325 | ||
cleanup
|
326 |
C<join>でテーブルの結合を行うことができます。 |
update pod
|
327 | |
328 |
次のSQLが実行されます。 |
|
329 | ||
cleanup
|
330 |
select company.name as company__name |
331 |
from book |
|
cleanup
|
332 |
left outer join company on book.company_id = company.id |
cleanup
|
333 |
where book.name = ?; |
cleanup
|
334 | |
335 |
bookテーブルのcompany_id列とcompanyテーブルのidが左外部結合されます。 |
|
336 |
次のSQLが実行されます。 |
|
337 | ||
338 |
C<join>されるのは、C<where>やC<column>にテーブル名が含まれている |
|
339 |
場合だけであることに注意してください。 |
|
340 |
次のように指定した場合は結合の必要はないと判断されjoinはされません。 |
|
341 | ||
342 |
my $result = $dbi->select( |
|
343 |
table => 'book', |
|
344 |
where => {'name' => 'Perl'}, |
|
345 |
join => ['left outer join company on book.company_id = company.id] |
|
346 |
); |
|
347 | ||
update pod
|
348 |
次のSQLが実行されます。 |
added experimental expand me...
|
349 | |
cleanup
|
350 |
select * from book where book.name = ?; |
added experimental expand me...
|
351 | |
update pod
|
352 |
次のサンプルです。 |
added experimental expand me...
|
353 | |
354 |
my $result = $dbi->select( |
|
remove DBIx::Custom::Model
|
355 |
table => 'book', |
added experimental expand me...
|
356 |
where => {author => 'Ken'}, |
updated document
|
357 |
append => 'for update', |
added experimental expand me...
|
358 |
); |
359 | ||
cleanup
|
360 |
C<mycolumn()>やC<column()>を使用すると簡単に列名を指定できます。 |
361 | ||
362 |
my $result = $dbi->select( |
|
363 |
table => 'book', |
|
364 |
column => [ |
|
365 |
$dbi->mycolumn('book' => ['name']), |
|
366 |
$dbi->column('company' => ['id', 'name']) |
|
367 |
], |
|
368 |
join => ['left outer join company on book.company_id = company.id] |
|
369 |
); |
|
370 | ||
371 |
次のSQLが実行されます。 |
|
372 | ||
373 |
select book.name as name, |
|
374 |
company.id as comapny__id, |
|
375 |
company.name as company__name |
|
376 |
from book |
|
377 |
left outer join company on book.company_id = company.id |
|
378 | ||
update pod
|
379 |
C<append>はSQLの末尾に追加される文字列です。 |
380 | ||
381 |
次のSQLが実行されます。 |
|
updated document
|
382 | |
updated document
|
383 |
select * book where author = ? for update; |
updated document
|
384 | |
updated document
|
385 |
またC<append>は、C<select>だけでなくC<insert()>、C<update()>、C<update_all()> |
386 |
C<delete()>、C<delete_all()>、C<select()>で使用することもできます。 |
|
updated document
|
387 | |
update pod
|
388 |
=head3 SQLの実行 C<execute()> |
removed experimental txn_sco...
|
389 | |
update pod
|
390 |
SQLを実行するにはC<execute()>を使用します。 |
removed experimental txn_sco...
|
391 | |
392 |
$dbi->execute("select * from book;"); |
|
393 | ||
updated pod
|
394 |
パラメーターを処理してSQLを実行します。 |
removed experimental txn_sco...
|
395 | |
396 |
$dbi->execute( |
|
updated pod
|
397 |
"select * from book title = :title and author = :author;" |
removed experimental txn_sco...
|
398 |
param => {title => 'Perl', author => 'Ken'} |
399 |
); |
|
400 | ||
update pod
|
401 |
次のSQLが実行されます。 |
removed experimental txn_sco...
|
402 | |
403 |
select * from book title = ? and author = ?; |
|
404 | ||
update pod
|
405 |
プレースホルダにtitleとauthorの値が埋め込まれます。 |
removed experimental txn_sco...
|
406 | |
updated pod
|
407 |
パラメーターについてはL<5. パラメーター/"5. パラメーター">を見てください。 |
removed experimental txn_sco...
|
408 | |
update pod
|
409 |
またC<execute()>のSQLの末尾にはセミコロンを置く必要はありません。 |
removed experimental txn_sco...
|
410 | |
411 |
$dbi->execute('select * from book'); |
|
412 | ||
updated document
|
413 |
=head2 3. 行のフェッチ |
414 | ||
updated document
|
415 |
C<select()>メソッドの戻り値はL<DBIx::Custom::Result>オブジェクトです。 |
update pod
|
416 |
行をフェッチするためのさまざまなメソッドがあります。 |
updated document
|
417 | |
update pod
|
418 |
=head3 1行づつフェッチ(配列) C<fetch()> |
updated document
|
419 | |
updated document
|
420 |
一行フェッチして配列のリファレンスに格納するにはC<fetch()>を使用します。 |
updated document
|
421 | |
update pod
|
422 |
my $row = $result->fetch; |
423 | ||
424 |
以下のようにすべての行を取得することができます。 |
|
425 | ||
updated document
|
426 |
while (my $row = $result->fetch) { |
updated document
|
427 |
my $title = $row->[0]; |
428 |
my $author = $row->[1]; |
|
updated document
|
429 |
} |
430 | ||
update pod
|
431 |
=head3 最初の行だけフェッチ(配列) C<fetch_first()> |
updated document
|
432 | |
updated document
|
433 |
一行だけフェッチして配列のリファレンスに格納するにはC<fetch_first()> |
434 |
を使用します。 |
|
updated document
|
435 | |
436 |
my $row = $result->fetch_first; |
|
437 | ||
update pod
|
438 |
ステートメントハンドルのC<finish()>が実行される |
439 |
ので残りの行をフェッチできません。 |
|
updated document
|
440 | |
update pod
|
441 |
=head3 複数行を順にフェッチ(配列) C<fetch_multi()> |
updated document
|
442 | |
updated document
|
443 |
複数行をフェッチして配列のリファレンスを要素に持つ |
444 |
配列のリファレンスに格納するにはC<fetch_multi()>を使用します。 |
|
updated document
|
445 | |
updated document
|
446 |
while (my $rows = $result->fetch_multi(2)) { |
447 |
my $title0 = $rows->[0][0]; |
|
448 |
my $author0 = $rows->[0][1]; |
|
449 |
|
|
450 |
my $title1 = $rows->[1][0]; |
|
451 |
my $author1 = $rows->[1][1]; |
|
updated document
|
452 |
} |
453 | ||
update pod
|
454 |
取り出したい行数を引数に指定します。 |
updated document
|
455 | |
update pod
|
456 |
次のようなデータを取得できます。 |
updated document
|
457 | |
458 |
[ |
|
459 |
['Perl', 'Ken'], |
|
460 |
['Ruby', 'Mark'] |
|
461 |
] |
|
462 | ||
update pod
|
463 |
=head3 すべての行をフェッチ(配列) C<fetch_all> |
updated document
|
464 | |
updated document
|
465 |
すべての行をフェッチして配列のリファレンスを要素に持つ |
466 |
配列のリファレンスに格納するにはC<fetch_all()>を使用します。 |
|
updated document
|
467 | |
468 |
my $rows = $result->fetch_all; |
|
469 | ||
updated document
|
470 |
すべての行を格納した次のようなデータを取得できます。 |
471 | ||
472 |
[ |
|
473 |
['Perl', 'Ken'], |
|
474 |
['Ruby', 'Mark'] |
|
475 |
] |
|
476 | ||
update pod
|
477 |
=head3 1行づつフェッチ(ハッシュ) C<fetch_hash()> |
updated document
|
478 | |
updated document
|
479 |
一行フェッチしてハッシュのリファレンスに格納するにはC<fetch_hash()>を使用します。 |
updated document
|
480 | |
481 |
while (my $row = $result->fetch_hash) { |
|
482 |
my $title = $row->{title}; |
|
483 |
my $author = $row->{author}; |
|
484 |
} |
|
485 | ||
update pod
|
486 |
=head3 最初の行だけフェッチ(ハッシュ) C<fetch_hash_first()> |
updated document
|
487 | |
updated document
|
488 |
一行だけフェッチしてハッシュのリファレンスに格納するには |
489 |
C<fetch_hash_first()>を使用します。 |
|
updated document
|
490 | |
491 |
my $row = $result->fetch_hash_first; |
|
492 | ||
update pod
|
493 |
ステートメントハンドルのC<finish()>が実行される |
494 |
ので残りの行をフェッチできません。 |
|
updated document
|
495 | |
update pod
|
496 |
=head3 複数行をフェッチ(ハッシュ) C<fetch_hash_multi()> |
updated document
|
497 | |
updated document
|
498 |
複数行をフェッチしてハッシュのリファレンスを要素に持つ |
499 |
配列のリファレンスに格納するにはC<fetch_hash_multi()> |
|
500 |
を使用します。 |
|
updated document
|
501 | |
502 |
while (my $rows = $result->fetch_hash_multi(5)) { |
|
updated document
|
503 |
my $title0 = $rows->[0]{title}; |
504 |
my $author0 = $rows->[0]{author}; |
|
505 |
my $title1 = $rows->[1]{title}; |
|
506 |
my $author1 = $rows->[1]{author}; |
|
updated document
|
507 |
} |
508 | ||
updated document
|
509 |
引数には取り出したい行数を指定します。 |
510 | ||
update pod
|
511 |
次のようなデータを取得できます。 |
updated document
|
512 | |
513 |
[ |
|
514 |
{title => 'Perl', author => 'Ken'}, |
|
515 |
{title => 'Ruby', author => 'Mark'} |
|
516 |
] |
|
517 | ||
update pod
|
518 |
=head3 すべての行をフェッチ(ハッシュ) C<fetch_hash_all()> |
updated document
|
519 | |
updated document
|
520 |
すべての行をフェッチしてハッシュのリファレンスを要素に持つ |
521 |
配列のリファレンスに格納するにはC<fetch_hash_all()> |
|
522 |
を使用します。 |
|
updated document
|
523 | |
524 |
my $rows = $result->fetch_hash_all; |
|
525 | ||
update pod
|
526 |
次のようなデータを取得できます。 |
updated document
|
527 | |
528 |
[ |
|
529 |
{title => 'Perl', author => 'Ken'}, |
|
530 |
{title => 'Ruby', author => 'Mark'} |
|
531 |
] |
|
532 | ||
update pod
|
533 |
=head3 ステートメントハンドル C<sth()> |
updated document
|
534 | |
update pod
|
535 |
ステートメントハンドル取得したい場合は |
536 |
<sth()>を使用します。 |
|
updated document
|
537 | |
538 |
my $sth = $result->sth; |
|
539 | ||
renamed dbi_options to dbi_o...
|
540 |
=head2 4. フィルタリング |
541 | ||
update pod
|
542 |
L<DBIx::Custom>は値のフィルタリング機能を提供します。 |
543 | ||
544 |
たとえば、データをデータベースに登録するときは |
|
545 |
L<Time::Piece>オブジェクトからデータベースの日付のフォーマットに、 |
|
546 |
データベースからデータを取得するときは、 |
|
547 |
データベースの日付のフォーマットからL<Time::Piece>オブジェクト |
|
548 |
に変換を行いたいと思うことでしょう。 |
|
renamed dbi_options to dbi_o...
|
549 | |
update pod
|
550 |
=head3 フィルタの登録 C<register_filter()> |
renamed dbi_options to dbi_o...
|
551 | |
552 |
フィルタを登録するにはC<register_filter()>を使用します。 |
|
553 | ||
554 |
$dbi->register_filter( |
|
555 |
# Time::Piece object to DATE format |
|
556 |
tp_to_date => sub { |
|
557 |
my $date = shift; |
|
558 | ||
559 |
return '0000-00-00' unless $tp; |
|
560 |
return $tp->strftime('%Y-%m-%d'); |
|
561 |
}, |
|
562 |
|
|
563 |
# DATE to Time::Piece object |
|
564 |
date_to_tp => sub { |
|
565 |
my $date = shift; |
|
566 | ||
567 |
return if $date eq '0000-00-00'; |
|
568 |
return Time::Piece->strptime($date, '%Y-%m-%d'); |
|
569 |
}, |
|
570 |
); |
|
571 | ||
572 |
登録したフィルタはC<apply_filter()>などで利用することができます。 |
|
573 | ||
update pod
|
574 |
=head3 フィルタの適用 C<apply_filter()> |
renamed dbi_options to dbi_o...
|
575 | |
576 |
作成したフィルタを適用するには、C<apply_filter()>を使用します。 |
|
577 | ||
578 |
$dbi->apply_filter('book', |
|
579 |
issue_date => {out => 'tp_to_date', in => 'date_to_tp'}, |
|
580 |
first_issue_date => {out => 'tp_to_date', in => 'date_to_tp'} |
|
581 |
); |
|
582 | ||
update pod
|
583 |
第一引数はテーブル名です。第1引数より後の引数は、列名とフィルタルールのペアを記述します。 |
renamed dbi_options to dbi_o...
|
584 |
フィルタルールのoutには、データベースにデータを送信するときに適用するフィルタを、 |
585 |
フィルタルールのinには、データベースからデータを取得するときに適用するフィルタを |
|
update pod
|
586 |
記述します。 |
587 | ||
588 |
フィルタとしてコードリファレンスを |
|
renamed dbi_options to dbi_o...
|
589 |
指定することもできます。 |
590 | ||
591 |
issue_date => {out => sub { ... }, in => sub { ... }} |
|
592 | ||
593 |
適用されたフィルタはC<insert()>、C<update()>、C<update_all()>、C<delete()>、 |
|
594 |
C<delete_all()>、C<select()>で有効になります。 |
|
595 | ||
596 |
my $tp = Time::Piece->strptime('2010/10/14', '%Y/%m/%d'); |
|
597 |
my $result = $dbi->select(table => 'book', where => {issu_date => $tp}); |
|
598 | ||
599 |
データベースにデータが送信されるときに、L<Time::Piece>オブジェクトは |
|
600 |
データベースの日付のフォーマット「2010-10-14」に変換されます。 |
|
601 | ||
update pod
|
602 |
データをフェッチするときには、データベースの日付のフォーマットは |
603 |
L<Time::Piece>オブジェクトに変換されます。 |
|
renamed dbi_options to dbi_o...
|
604 | |
605 |
my $row = $resutl->fetch_hash_first; |
|
606 |
my $tp = $row->{issue_date}; |
|
607 | ||
update pod
|
608 |
テーブル名を含む列名を使用することもできます。 |
removed experimental expand
|
609 | |
610 |
$dbi->select( |
|
611 |
table => 'book', |
|
612 |
where => {'book.title' => 'Perl', 'book.author' => 'Ken'} |
|
613 |
); |
|
614 | ||
update pod
|
615 |
フェッチを行う場合に"TABLE__COLUMN"という名前を使用した場合もフィルタは |
616 |
有効になります。 |
|
617 | ||
618 |
my $result = $dbi->execute( |
|
619 |
"select issue_date as book__issue_date from book"); |
|
620 | ||
621 |
C<in>フィルタの後に実行されるC<end>フィルタを適用することもできます。 |
|
622 | ||
623 |
$dbi->apply_filter('book', |
|
624 |
issue_date => {out => 'tp_to_date', in => 'date_to_tp', |
|
625 |
end => 'tp_to_displaydate'}, |
|
626 |
); |
|
627 | ||
update pod
|
628 |
=head3 個別のフィルタ C<filter> |
renamed dbi_options to dbi_o...
|
629 | |
removed experimental txn_sco...
|
630 |
個別にフィルタを適用することもできます。 |
renamed dbi_options to dbi_o...
|
631 |
個別のフィルタはC<apply_filter()>で適用したフィルタを上書きます。 |
removed experimental txn_sco...
|
632 | |
update pod
|
633 |
データを送信する場合に個別のフィルタを適用するには、C<filter>オプションを使用します。 |
634 |
このオプションはC<insert()>、C<update()>、 |
|
removed experimental txn_sco...
|
635 |
C<update_all()>、C<delete()>、C<delete_all()>、C<select()>、C<execute()> |
636 |
で使用することができます。 |
|
renamed dbi_options to dbi_o...
|
637 | |
removed experimental txn_sco...
|
638 |
$dbi->insert( |
639 |
table => 'book', |
|
640 |
param => {issue_date => $tp, first_issue_date => $tp}, |
|
641 |
filter => {issue_date => 'tp_to_date', first_issue_date => 'tp_to_date'} |
|
642 |
); |
|
643 | ||
644 |
C<execute()>の例を示します。 |
|
645 | ||
646 |
my $sql = <<"EOS"; |
|
647 |
select YEAR(issue_date) as issue_year |
|
648 |
from book |
|
649 |
where YEAR(issue_date) = {? issue_year} |
|
650 |
EOS |
|
651 |
|
|
652 |
my $result = $dbi->execute( |
|
653 |
$sql, |
|
654 |
param => {issue_year => '2010'}, |
|
655 |
filter => {issue_year => 'tp_to_year'} |
|
656 |
); |
|
657 | ||
update pod
|
658 |
行をフェッチするときにも個別のフィルタを適用することができます。 |
659 |
C<DBIx::Custom::Result>のC<filter()>を使用します。 |
|
renamed dbi_options to dbi_o...
|
660 | |
removed experimental txn_sco...
|
661 |
$result->filter(issue_year => 'year_to_tp'); |
662 | ||
selection can contain where ...
|
663 |
C<remove_filter()>でフィルタを取り除くこともできます。 |
664 | ||
665 |
$result->remove_filter |
|
666 | ||
update pod
|
667 |
=head3 最後のフィルタリング : C<end_filter()> |
removed experimental txn_sco...
|
668 | |
update pod
|
669 |
最後にもうひとつフィルタを追加することができます。 |
670 |
最終的な出力を作成する場合に便利です。 |
|
671 |
最後のフィルタを登録するにはC<end_filter()>を使用します。 |
|
removed experimental txn_sco...
|
672 | |
673 |
$result->end_filter(issue_date => sub { |
|
674 |
my $tp = shift; |
|
675 |
|
|
676 |
return '' unless $tp; |
|
677 |
return $tp->strftime('%Y/%m/%d %h:%m:%s (%a)'); |
|
678 |
}); |
|
679 | ||
update pod
|
680 |
この例ではL<Time::Piece>オブジェクトを読みやすい書式に変換しています。 |
removed experimental txn_sco...
|
681 | |
added experimental DBIx::Cus...
|
682 |
最後のフィルタリングをC<remove_filter()>で取り除くこともできます。 |
683 | ||
684 |
$result->remove_end_filter; |
|
685 | ||
update pod
|
686 |
=head3 フィルタの適用の自動化 C<each_column()> |
removed experimental txn_sco...
|
687 | |
update pod
|
688 |
日付型の列は自動的にフィルタを適用できると便利です。 |
689 |
列のすべての情報を処理するためのC<each_column()>を利用することができます。 |
|
removed experimental txn_sco...
|
690 | |
691 |
$dbi->each_column( |
|
692 |
sub { |
|
693 |
my ($self, $table, $column, $info) = @_; |
|
694 |
|
|
695 |
my $type = $info->{TYPE_NAME}; |
|
696 |
|
|
697 |
my $filter = $type eq 'DATE' ? {out => 'tp_to_date', in => 'date_to_tp'} |
|
698 |
: $type eq 'DATETIME' ? {out => 'tp_to_datetime', in => 'datetime_to_tp'} |
|
699 |
: undef; |
|
700 |
|
|
701 |
$self->apply_filter($table, $column, $filter) |
|
702 |
if $filter; |
|
703 |
} |
|
704 |
); |
|
renamed dbi_options to dbi_o...
|
705 | |
removed experimental txn_sco...
|
706 |
each_columnはコールバックを受け取ります。コールバックの引数は |
update pod
|
707 |
L<DBIx::Custom>オブジェクト、テーブル名、列名、列の情報です。 |
removed experimental txn_sco...
|
708 |
列の型名の情報をもとに自動的に、フィルタを適用しています。 |
709 | ||
updated pod
|
710 |
=head2 5. パラメーター |
updated document
|
711 | |
updated pod
|
712 |
=head3 パラメーターの基本 |
updated document
|
713 | |
updated pod
|
714 |
SQLの中にパラメーターを埋め込むことができます。 |
updated document
|
715 | |
updated pod
|
716 |
select * from book where title = :title and author like :author; |
updated document
|
717 | |
updated pod
|
718 |
:titleと:authorの部分がパラメーターです。 |
update pod
|
719 |
|
updated pod
|
720 |
パラメーターはSQLが実行される前に展開されます。 |
update pod
|
721 | |
722 |
select * from book where title = ? and author like ?; |
|
updated document
|
723 | |
updated pod
|
724 |
パラメーターを含むSQLを実行するにはC<execute()>を使用します。 |
updated document
|
725 | |
updated pod
|
726 |
my $sql = "select * from book where author = :author and title like :title;" |
update pod
|
727 |
$dbi->execute($sql, param => {title => 'Perl', author => '%Ken%'}); |
updated document
|
728 | |
update pod
|
729 |
C<param>オプションを使って、プレースホルダに埋め込みたい値を |
730 |
ハッシュリファレンスで指定することができます。 |
|
updated document
|
731 | |
update pod
|
732 |
C<execute()>においてもC<filter>を指定することができます。 |
update pod
|
733 | |
734 |
$dbi->execute($sql, param => {title => 'Perl', author => '%Ken%'} |
|
735 |
filter => {title => 'to_something'); |
|
736 | ||
update pod
|
737 |
C<execute>ではC<apply_filter()>で適用されたフィルタ |
738 |
は有効ではないということに注意してください。 |
|
update pod
|
739 |
C<apply_filter()>で適用されたフィルタを有効にするには、 |
improved table search in col...
|
740 |
C<table>オプションを利用します。 |
update pod
|
741 | |
improved table search in col...
|
742 |
$dbi->execute($sql, table => ['author', 'book']); |
update pod
|
743 | |
improved table search in col...
|
744 |
後ろで適用したフィルタのほうが優先順位が高くなります。 |
update pod
|
745 | |
update pod
|
746 |
=head3 同名の列の扱い |
updated document
|
747 | |
updated pod
|
748 |
同名の列を含むパラメーターがある場合でも大丈夫です。 |
update pod
|
749 |
二つの日付で比較しなければならない場合を |
update pod
|
750 |
考えて見ましょう。 |
updated document
|
751 | |
updated pod
|
752 |
my $sql = "select * from table where date > :date and date < :date;"; |
updated document
|
753 | |
update pod
|
754 |
このような場合はパラメータの値を配列のリファレンスで指定します。 |
removed experimental txn_sco...
|
755 | |
update pod
|
756 |
my $dbi->execute($sql, param => {date => ['2010-10-01', '2012-02-10']}); |
757 | ||
removed experimental txn_sco...
|
758 |
=head2 6. Where句の動的な生成 |
759 | ||
added experimental not_exist...
|
760 |
=head3 Where句の動的な生成 where() |
761 | ||
762 |
複数の検索条件を指定して、検索を行いたい場合があります。 |
|
763 |
次の3つのケースのwhere句を考えてみましょう。 |
|
764 | ||
765 |
titleの値だけで検索したい場合 |
|
766 | ||
updated pod
|
767 |
where title = :title |
added experimental not_exist...
|
768 | |
769 |
authorの値だけで検索したい場合 |
|
770 | ||
updated pod
|
771 |
where author = :author |
added experimental not_exist...
|
772 | |
773 |
titleとauthorの両方の値で検索したい場合 |
|
774 | ||
updated pod
|
775 |
where title = :title and author = :author |
added experimental not_exist...
|
776 | |
777 |
L<DBIx::Custom>では動的なWhere句の生成をサポートしています。 |
|
778 |
まずC<where()>でL<DBIx::Custom::Where>オブジェクトを生成します。 |
|
779 | ||
780 |
my $where = $dbi->where; |
|
781 | ||
782 |
次にC<clause()>を使用してwhere句を記述します。 |
|
783 | ||
784 |
$where->clause( |
|
updated pod
|
785 |
['and', 'title = :title', 'author = :author'] |
added experimental not_exist...
|
786 |
); |
787 | ||
788 |
clauseの指定方法は次のようになります。 |
|
789 | ||
updated pod
|
790 |
['or' あるいは 'and', パラメーター1, パラメーター2, パラメーター3] |
added experimental not_exist...
|
791 | |
792 |
第一引数にはorあるいはandを指定します。第二引数以降には |
|
updated pod
|
793 |
検索条件をパラメーターを使って記述します。 |
added experimental not_exist...
|
794 | |
795 |
C<clause>の指定は入れ子にすることもでき、さらに複雑な条件 |
|
796 |
を記述することもできます。 |
|
797 | ||
798 |
['and', |
|
updated pod
|
799 |
'title = :title', |
800 |
['or', 'author = :author', 'date like :date'] |
|
added experimental not_exist...
|
801 |
] |
802 | ||
updated pod
|
803 |
これは "title = :title and ( author = :author or date like :date )" 意味しています。 |
update pod
|
804 | |
805 |
C<clause>を設定した後にC<param>にパラメータを指定します。 |
|
added experimental not_exist...
|
806 |
|
update pod
|
807 |
$where->param({title => 'Perl'}); |
added experimental not_exist...
|
808 | |
809 |
この例ではtitleだけがパラメータに含まれています。 |
|
810 | ||
811 |
この後C<to_string()>を実行すると$paramに含まれるパラメータを満たす |
|
812 |
where句を生成することができます。 |
|
813 | ||
814 |
my $where_clause = $where->to_string; |
|
815 | ||
816 |
パラメータはtitleだけですので、次のようなwhere句が生成されます。 |
|
817 | ||
updated pod
|
818 |
where title = :title |
added experimental not_exist...
|
819 | |
cleanup
|
820 |
またL<DBIx::Custom>は文字列の評価をオーバーロードして、C<to_string()> |
added experimental not_exist...
|
821 |
を呼び出すようにしていますので、次のようにしてwhere句を生成することも |
822 |
できます。 |
|
823 | ||
824 |
my $where_clause = "$where"; |
|
825 | ||
826 |
これはSQLの中にwhere句を埋め込むときにとても役立つ機能です。 |
|
827 | ||
make delete() using where ob...
|
828 |
=head3 同一の列名を含む場合 |
added experimental not_exist...
|
829 | |
updated pod
|
830 |
パラメーターの中に同一の名前を持つものが存在した場合でも動的に |
make delete() using where ob...
|
831 |
where句を作成することができます。 |
added experimental not_exist...
|
832 | |
make delete() using where ob...
|
833 |
たとえば、パラメータとして開始日付と終了日付を受け取ったことを |
834 |
考えてみてください。 |
|
added experimental not_exist...
|
835 | |
make delete() using where ob...
|
836 |
my $param = {start_date => '2010-11-15', end_date => '2011-11-21'}; |
added experimental not_exist...
|
837 | |
update pod
|
838 |
この場合はパラメータの値を配列のリファレンスにしてください。 |
added experimental not_exist...
|
839 | |
make delete() using where ob...
|
840 |
my $p = {date => ['2010-11-15', '2011-11-21']}; |
added experimental not_exist...
|
841 | |
updated pod
|
842 |
同名の列を含むパラメーターに順番に埋め込むことができます。 |
added experimental not_exist...
|
843 | |
make delete() using where ob...
|
844 |
$where->clause( |
updated pod
|
845 |
['and', 'date > :date', 'date < :date'] |
make delete() using where ob...
|
846 |
); |
847 |
$where->param($p); |
|
848 | ||
849 |
また開始日付が存在しない場合は次のようなデータを作成します。 |
|
850 | ||
851 |
my $p = {date => [$dbi->not_exists, '2011-11-21']}; |
|
852 | ||
update pod
|
853 |
C<not_exists()>でDBIx::Custom::NotExistsオブジェクトを |
make delete() using where ob...
|
854 |
取得できます。これは対応する値が存在しないことを示すためのものです。 |
855 | ||
856 |
また終了日付が存在しない場合は次のようなデータを作成します。 |
|
857 | ||
858 |
my $p = {date => ['2010-11-15']}; |
|
added experimental not_exist...
|
859 | |
make delete() using where ob...
|
860 |
どちらも存在しない場合は次のようなデータを作成します。 |
861 | ||
862 |
my $p = {date => []}; |
|
863 | ||
864 |
少し難しいので一番簡単に作成できるロジックを示しておきます。 |
|
865 | ||
866 |
my @date; |
|
867 |
push @date, exists $param->{start_date} ? $param->{start_date} |
|
868 |
: $dbi->not_exists; |
|
869 |
push @date, $param->{end_date} if exists $param->{end_date}; |
|
870 |
my $p = {date => \@date}; |
|
871 | ||
872 |
=head3 C<select()>との連携 |
|
873 | ||
update pod
|
874 |
L<DBIx::Custom::Where>オブジェクトは |
875 |
C<select()>のC<where>に直接渡すことが |
|
make delete() using where ob...
|
876 |
できます。 |
877 |
|
|
878 |
my $where = $dbi->where; |
|
879 |
$where->clause(...); |
|
880 |
$where->param($param); |
|
881 |
my $result = $dbi->select(table => 'book', where => $where); |
|
882 | ||
update pod
|
883 |
あるいはC<update()>、C<delete()>のwhereに指定することも可能です。 |
make delete() using where ob...
|
884 | |
885 |
=head3 C<execute()>との連携 |
|
886 | ||
887 |
C<execute()>との連携です。SQLを作成するときに埋め込むことができます。 |
|
888 | ||
889 | ||
890 |
my $where = $dbi->where; |
|
891 |
$where->clause(...); |
|
892 |
$where->param($param); |
|
893 | ||
update pod
|
894 |
my $sql = <<"EOS"; |
make delete() using where ob...
|
895 |
select * from book; |
896 |
$where |
|
897 |
EOS |
|
added experimental not_exist...
|
898 | |
make delete() using where ob...
|
899 |
$dbi->execute($sql, param => $param); |
added experimental not_exist...
|
900 | |
add feture. all model class ...
|
901 |
=head2 7. モデル |
update pod
|
902 | |
add feture. all model class ...
|
903 |
=head3 モデル |
update pod
|
904 | |
removed experimental base_ta...
|
905 |
ソースコードの見通しをよくするために、 |
add feture. all model class ...
|
906 |
L<DBIx::Custom::Model>を継承してモデルを作成することができます。 |
update pod
|
907 | |
add experimental DBIx::Custo...
|
908 |
まず最初にモデルの元になるクラスを<DBIx::Custom::Model> |
909 |
を継承して作成します。 |
|
update pod
|
910 | |
add experimental DBIx::Custo...
|
911 |
package MyModel; |
912 |
|
|
913 |
use base 'DBIx::Custom::Model'; |
|
update pod
|
914 | |
add experimental DBIx::Custo...
|
915 |
次に個々のモデルクラスを作成します。 |
update pod
|
916 | |
add experimental DBIx::Custo...
|
917 |
MyModel::book |
update pod
|
918 | |
add experimental DBIx::Custo...
|
919 |
package MyModel::book; |
920 |
|
|
921 |
use base 'MyModel'; |
|
922 |
|
|
923 |
sub insert { ... } |
|
924 |
sub list { ... } |
|
update pod
|
925 | |
add experimental DBIx::Custo...
|
926 |
MyModel::company |
add feture. all model class ...
|
927 | |
add experimental DBIx::Custo...
|
928 |
package MyModel::company; |
add feture. all model class ...
|
929 |
|
add experimental DBIx::Custo...
|
930 |
use base 'MyModel'; |
931 |
|
|
932 |
sub insert { ... } |
|
933 |
sub list { ... } |
|
add feture. all model class ...
|
934 | |
add experimental DBIx::Custo...
|
935 |
このように作成したモジュールを次のように配置してください。 |
add feture. all model class ...
|
936 | |
937 |
MyModel.pm |
|
938 |
MyModel / book.pm |
|
939 |
/ company.pm |
|
add experimental DBIx::Custo...
|
940 | |
941 |
このように作成したモデルはC<include_model()>で取り込むことができます。 |
|
942 | ||
943 |
$dbi->include_model('MyModel'); |
|
944 | ||
945 |
第一引数は、モデルの名前空間になります。 |
|
946 | ||
add feture. all model class ...
|
947 |
モデルは次のように利用することができます。 |
948 | ||
949 |
my $result = $dbi->model('book')->list; |
|
950 | ||
951 |
モデルではテーブル名を指定することなしに |
|
removed experimental base_ta...
|
952 |
C<insert()>, C<update()>, C<update_all()>, |
953 |
C<delete()>, C<delete_all()>, C<select()>などのメソッドを |
|
add feture. all model class ...
|
954 |
利用できます。 |
update pod
|
955 | |
add feture. all model class ...
|
956 |
$dbi->model('book')->insert(param => $param); |
update pod
|
957 | |
add experimental DBIx::Custo...
|
958 |
またモデルクラスでC<primary_key>の設定がなされていれば、 |
959 |
プライマリキーを指定することなしに |
|
update pod
|
960 |
C<insert_at>, C<update_at()>, C<delete_at()>, C<select_at()>のメソッドを |
add experimental DBIx::Custo...
|
961 |
利用できます。 |
962 | ||
963 |
$dbi->model('book')->delete_at(where => 123); |
|
964 | ||
add feture. all model class ...
|
965 |
モデルはL<DBIx::Custom::Model>です。 |
update pod
|
966 | |
add feture. all model class ...
|
967 |
必要であれば、C<table()>でテーブル名を取得することができます。 |
update pod
|
968 | |
add feture. all model class ...
|
969 |
my $table = $model->table; |
removed experimental base_ta...
|
970 | |
971 |
L<DBIx::Custom>オブジェクトを取得することもできます。 |
|
972 | ||
add feture. all model class ...
|
973 |
my $dbi = $model->dbi; |
removed experimental base_ta...
|
974 | |
975 |
L<DBIx::Custom>とL<DBI>のすべてのメソッドを呼び出すこともできます。 |
|
update pod
|
976 | |
update pod
|
977 |
# DBIx::Custom method |
add feture. all model class ...
|
978 |
$model->execute($sql); |
update pod
|
979 |
|
980 |
# DBI method |
|
add feture. all model class ...
|
981 |
$model->begin_work; |
982 |
$model->commit; |
|
update pod
|
983 | |
add models() attribute
|
984 |
すべてのモデル名を取得したい場合はC<models()>のキーを取得してください。 |
985 | ||
986 |
my @models = keys %{$self->models}; |
|
987 | ||
add DBIx::Custom::Model fore...
|
988 |
モデルにはプライマリーキーを設定することもできます。 |
989 | ||
990 |
$model->primary_key(['id', 'number_id']); |
|
991 | ||
update pod
|
992 |
ここで設定したプライマリーキーはC<insert_at>, C<update_at()>, C<delete_at()>, |
add DBIx::Custom::Model fore...
|
993 |
C<select_at()>で利用されます。 |
994 | ||
add experimental DBIx::Custo...
|
995 |
C<filter>でC<apply_filter()>で適用されるフィルタを定義しておくこともできます。 |
996 | ||
997 |
$model->filter({ |
|
998 |
title => {out => ..., in => ..., end => ...}, |
|
999 |
author => {out => ..., in => ..., end => ...} |
|
1000 |
}); |
|
1001 | ||
1002 |
このフィルタはC<include_model()>を呼び出したときに自動的に適用されます。 |
|
1003 | ||
add DBIx::Custom::Model colu...
|
1004 |
モデルには列名を設定することもできます。 |
1005 | ||
1006 |
$model->columns(['id', 'number_id']); |
|
1007 | ||
add experimental setup_model...
|
1008 |
列名はC<setup_model()>で自動的に設定することができます。 |
1009 |
このメソッドはC<include_model()>の後で呼び出してください。 |
|
1010 | ||
1011 |
$dbi->setup_model; |
|
1012 | ||
cleanup
|
1013 |
モデルにはC<join>を設定することもできます。 |
cleanup
|
1014 | |
cleanup
|
1015 |
$model->join(['left outer join company on book.company_id = company.id']); |
cleanup
|
1016 | |
cleanup
|
1017 |
ここで設定したC<join>はC<select()>, C<select_at()>で利用されます。 |
cleanup
|
1018 | |
add experimental DBIx::Custo...
|
1019 | |
add experimental DBIx::Custo...
|
1020 |
=head2 クラス名、モデル名、テーブル名 |
1021 | ||
1022 |
クラス名とモデル名とテーブル名の関係について書いておきます。 |
|
1023 |
通常はクラス名がモデル名に利用され、テーブル名にはモデル名が利用されます。 |
|
1024 | ||
1025 |
クラス名 モデル名 テーブル名 |
|
1026 |
book (クラス名) -> book (モデル名) -> book |
|
1027 | ||
1028 |
モデル名を変更することもできます。 |
|
1029 | ||
1030 |
package MyModel::book; |
|
1031 |
|
|
add experimental DBIx::Custo...
|
1032 |
use base 'MyModel'; |
1033 |
|
|
add experimental DBIx::Custo...
|
1034 |
__PACAKGE__->attr(name => 'book_model'); |
1035 | ||
1036 |
クラス名 モデル名 テーブル名 |
|
1037 |
book book_model (モデル名) -> book_model |
|
1038 | ||
1039 |
モデル名というのは、L<DBIx::Custom>のL<model()>で利用される名前です。 |
|
1040 | ||
1041 |
$dbi->model('book_model'); |
|
1042 | ||
1043 |
テーブル名を変更することもできます。 |
|
1044 | ||
1045 |
package MyModel::book; |
|
add experimental DBIx::Custo...
|
1046 | |
1047 |
use base 'MyModel'; |
|
add experimental DBIx::Custo...
|
1048 |
|
1049 |
__PACAKGE__->attr(table => 'book_table'); |
|
add experimental DBIx::Custo...
|
1050 |
|
add experimental DBIx::Custo...
|
1051 |
クラス名 モデル名 テーブル名 |
1052 |
book (クラス名) -> book book_table |
|
1053 | ||
1054 |
テーブル名というのは、実際にアクセスされるテーブルです。 |
|
1055 | ||
1056 |
$dbi->model('book')->insert(...); # book_tableにアクセス |
|
1057 | ||
cleanup
|
1058 |
=head2 列名の自動生成 : mycolumn(), column() |
add experimental DBIx::Custo...
|
1059 | |
cleanup
|
1060 |
列名の節を自動生成するにはC<mycolumn()>を使用します。 |
add experimental DBIx::Custo...
|
1061 |
C<table>とC<columns>の値が利用されます。 |
1062 | ||
cleanup
|
1063 |
my $column_clause = $model->mycolumn; |
add experimental DBIx::Custo...
|
1064 | |
1065 |
C<table>の値が'book'、C<column>の値が['id', 'name']で |
|
1066 |
あった場合は次のような列名の節が生成されます。 |
|
1067 | ||
1068 |
book.id as id, book.name as name |
|
1069 | ||
1070 |
このように列名の節を生成するのは、列名のあいまいさをなくすためです。 |
|
1071 | ||
cleanup
|
1072 |
また他のテーブルの列名から列名を自動生成することもできます。 |
add experimental DBIx::Custo...
|
1073 | |
cleanup
|
1074 |
my $column_clause = $model->column('company'); |
add experimental DBIx::Custo...
|
1075 | |
cleanup
|
1076 |
モデルのC<comparny>のC<column>の値が['id', 'name']で |
1077 |
あった場合は次のような列名の節が生成されます。 |
|
add experimental DBIx::Custo...
|
1078 | |
cleanup
|
1079 |
company.id as company__id, company.name as company__name |
add experimental DBIx::Custo...
|
1080 | |
add feture. all model class ...
|
1081 |
=head2 モデルのサンプル |
update pod
|
1082 | |
add feture. all model class ...
|
1083 |
モデルのサンプルです。 |
update pod
|
1084 | |
1085 |
package MyDBI; |
|
1086 |
|
|
1087 |
use base 'DBIx::Custom'; |
|
1088 |
|
|
1089 |
sub connect { |
|
1090 |
my $self = shift->SUPER::connect(@_); |
|
1091 |
|
|
add feture. all model class ...
|
1092 |
$self->include_model( |
1093 |
MyModel => [ |
|
removed experimental base_ta...
|
1094 |
'book', |
1095 |
'company' |
|
1096 |
] |
|
update pod
|
1097 |
); |
1098 |
} |
|
removed experimental base_ta...
|
1099 |
|
add feture. all model class ...
|
1100 |
package MyModel::book; |
1101 |
use base 'DBIx::Custom::Model'; |
|
removed experimental base_ta...
|
1102 |
|
add experimental update_at()...
|
1103 |
__PACKAGE__->attr('primary_key' => sub { ['id'] }; |
1104 |
|
|
removed experimental base_ta...
|
1105 |
sub insert { ... } |
1106 |
sub list { ... } |
|
1107 |
|
|
add feture. all model class ...
|
1108 |
package MyModel::company; |
1109 |
use base 'DBIx::Custom::Model'; |
|
add experimental update_at()...
|
1110 | |
1111 |
__PACKAGE__->attr('primary_key' => sub { ['id'] }; |
|
removed experimental base_ta...
|
1112 |
|
1113 |
sub insert { ... } |
|
1114 |
sub list { ... } |
|
update pod
|
1115 | |
1116 |
=head2 8. パフォーマンスの改善 |
|
updated document
|
1117 | |
update pod
|
1118 |
=head3 クエリの作成 |
updated document
|
1119 | |
update pod
|
1120 |
パフォーマンスが得られない場合はC<query>オプションを使って |
1121 |
クエリを作成してみてください。 |
|
update pod
|
1122 | |
update pod
|
1123 |
my $params = [ |
1124 |
{title => 'Perl', author => 'Ken'}, |
|
1125 |
{title => 'Good day', author => 'Tom'} |
|
1126 |
] |
|
1127 |
my $query = $dbi->insert(table => 'book', param => $params->[0], query => 1); |
|
update pod
|
1128 | |
update pod
|
1129 |
戻り値はL<DBIx::Custom::Query>オブジェクトです。 |
1130 |
作成したクエリはC<execute()>で実行することができます。 |
|
update pod
|
1131 | |
update pod
|
1132 |
foreach my $param (@$params) { |
1133 |
$dbi->execute($query, $param); |
|
1134 |
} |
|
1135 | ||
1136 |
ステートメントハンドルが再利用されるので、パフォーマンスが |
|
1137 |
改善されます。 |
|
1138 |
C<query>オプションはC<insert()>, C<update()>, C<update_all()>, |
|
1139 |
C<delete()>, C<delete_all()>で利用することができます. |
|
1140 | ||
1141 |
クエリを作成するメソッドに渡すパラメータと |
|
1142 |
C<execute()>に渡すパラメータの個数は同じでなければならない |
|
1143 |
ことに注意してください。 |
|
1144 | ||
1145 |
C<create_query()>を使って任意のSQLのクエリを作成 |
|
update pod
|
1146 |
することもできます。 |
updated document
|
1147 | |
1148 |
my $query = $dbi->create_query( |
|
update pod
|
1149 |
"insert into book {insert_param title author};"; |
updated document
|
1150 |
); |
1151 | ||
1152 | ||
update pod
|
1153 |
=head2 9. その他の機能 |
updated document
|
1154 | |
update pod
|
1155 |
=head3 メソッドの登録 |
updated document
|
1156 | |
update pod
|
1157 |
L<DBIx::Custom>オブジェクトにメソッドを追加することができます。 |
update pod
|
1158 |
C<method()>を使用します。 |
updated document
|
1159 | |
update pod
|
1160 |
$dbi->method( |
updated document
|
1161 |
update_or_insert => sub { |
1162 |
my $self = shift; |
|
update pod
|
1163 |
# something |
updated document
|
1164 |
}, |
1165 |
find_or_create => sub { |
|
1166 |
my $self = shift; |
|
update pod
|
1167 |
# something |
updated document
|
1168 |
} |
1169 |
); |
|
1170 | ||
update pod
|
1171 |
これらのメソッドは |
1172 |
L<DBIx::Custom>オブジェクトから呼び出すことができます。 |
|
updated document
|
1173 | |
1174 |
$dbi->update_or_insert; |
|
1175 |
$dbi->find_or_create; |
|
1176 | ||
removed experimental expand
|
1177 |
=head3 結果クラスの変更 |
1178 | ||
update pod
|
1179 |
結果クラスを変更することができます。 |
1180 |
デフォルトはL<DBIx::Custom::Result>です。 |
|
removed experimental expand
|
1181 | |
1182 |
package MyResult; |
|
1183 |
use base 'DBIx::Custom::Result'; |
|
1184 |
|
|
1185 |
sub some_method { ... } |
|
updated document
|
1186 | |
removed experimental expand
|
1187 |
1; |
1188 |
|
|
1189 |
package main; |
|
1190 |
|
|
1191 |
use MyResult; |
|
1192 |
|
|
1193 |
my $dbi = DBIx::Custom->connect(...); |
|
1194 |
$dbi->result_class('MyResult'); |
|
updated document
|
1195 | |
update pod
|
1196 |
=head1 サンプル |
1197 | ||
1198 |
以下のWikiでサンプルを見ることができます。 |
|
1199 | ||
1200 |
L<DBIx::Custom Wiki|https://github.com/yuki-kimoto/DBIx-Custom/wiki> |
|
1201 | ||
updated document
|
1202 |
=cut |