Newer Older
770 lines | 26.264kb
added experimental expand me...
yuki-kimoto authored on 2010-10-20
1
=encoding utf8
2

            
updated document
yuki-kimoto authored on 2010-10-22
3
=head1 NAME
added experimental expand me...
yuki-kimoto authored on 2010-10-20
4

            
pod fix
Yuki Kimoto authored on 2011-01-21
5
DBIx::Custom::Guide::Ja - DBIx::Customの日本語ガイド
added experimental expand me...
yuki-kimoto authored on 2010-10-20
6

            
7
=head1 ガイド
8

            
9
L<DBIx::Custom>はデータベースへのクエリの発行を簡単に行うための
10
クラスです。L<DBIx::Class>やL<DBIx::Simple>と同じように
updated document
Yuki Kimoto authored on 2011-01-20
11
L<DBI>のラッパクラスになっています。L<DBIx::Class>よりも簡単に、
12
L<DBIx::Simple>よりもはるかに柔軟なことを行うことができます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
13

            
14
L<DBIx::Custom>はO/Rマッパーではありません。O/Rマッパーは
15
便利ですが、O/Rマッパのたくさんの文法を覚える必要があります。
updated document
Yuki Kimoto authored on 2011-01-20
16
また、O/Rマッパによって生成されたSQLは非効率なことがありますし、
17
複雑なSQLを生成することができないので、
18
生のSQLを発行しなければならない場合がたくさんあります。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
19

            
updated document
Yuki Kimoto authored on 2011-01-20
20
L<DBIx::Custom>はO/Rマッパとは対照的な設計が行われています。
updated document
Yuki Kimoto authored on 2011-01-20
21
L<DBIx::Custom>の主な目的は、SQLを尊重しつつ、L<DBI>だけでは
updated document
Yuki Kimoto authored on 2011-01-20
22
とてもめんどうな作業を簡単にすることです。もしSQLについて
23
多くの知識を持っているならば、L<DBIx::Custom>でそのまま
updated document
Yuki Kimoto authored on 2011-01-20
24
活用することができます。
updated document
Yuki Kimoto authored on 2011-01-20
25

            
26
L<DBIx::Custom>の仕組みを簡単に説明しておきましょう。
27
L<DBIx::Custom>では、タグと呼ばれるものを
28
SQLの中に埋め込むことができます。
29

            
30
    select * from book where {= title} and {=author};
31

            
32
{}で囲まれた部分がタグです。このSQLは実際に実行されるときには
33
次のようにプレースホルダに展開されます。
34

            
updated document
Yuki Kimoto authored on 2011-01-20
35
    select * from book where title = ? and author = ?;
updated document
Yuki Kimoto authored on 2011-01-20
36

            
37
これらの展開にはどのような意味があるのでしょうかと質問
updated document
Yuki Kimoto authored on 2011-01-20
38
されることかと思います。この簡単な仕組みの上に非常にたくさんの
39
有用で便利で使いやすい機能が構築されます。それは以下のようなものです。
updated document
Yuki Kimoto authored on 2011-01-20
40

            
updated document
Yuki Kimoto authored on 2011-01-20
41
=over 4
updated document
Yuki Kimoto authored on 2011-01-20
42

            
updated document
Yuki Kimoto authored on 2011-01-20
43
=item 1. プレースホルダのパラメータをハッシュリファレンスで指定
updated document
Yuki Kimoto authored on 2011-01-20
44

            
updated document
Yuki Kimoto authored on 2011-01-20
45
L<DBI>をそのまま使うのであればプレースホルダのパラメータは配列
46
で指定する必要があります。
updated document
Yuki Kimoto authored on 2011-01-20
47

            
updated document
Yuki Kimoto authored on 2011-01-20
48
    $sth->execute(@bind);
49

            
50
L<DBIx::Custom>を利用するのであればハッシュリファレンスで指定すること
51
できます。
52
    
53
    my $param = {title => 'Perl', author => 'Ken'};
54
    $dbi->execute($sql, $param);
55

            
56
=item 2. パラメータのフィルタリング
57

            
58
たとえば、日付の列は、Perlで扱うときにはC<Time::Piece>などの日付オブジェクト
59
で扱い、データベースに格納するときはデータベースの日付型に変換したい
60
と思うのではないでしょうか。またデータベースから取り出すときは
61
データベースの日付型から日付オブジェクトに変換したと思うのでは
62
ないでしょうか。
63

            
64
このようなときはフィルタ機能を使うことができます。
65

            
66
まずフィルタを登録します。
67

            
68
    $dbi->register_filter(
69
        tp_to_date => sub {
70
            ...
71
        },
72
        date_to_tp => sub {
73
            ...
74
        }
75
    );
76

            
77
次にテーブルの各列にこのフィルタを適用します。
78

            
79
    $dbi->apply_filter('book',
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
80
        'issue_date' => {out => 'tp_to_date', in => 'date_to_tp'}
updated document
Yuki Kimoto authored on 2011-01-20
81
    );
82

            
83
outはPerlからデータベースに保存する方向、inはデータベースからPerlに取得する方向です。
84

            
85
SQLを発行するときにテーブルの指定を行えば、自動的にこのフィルタが適用されます。
86

            
87
    $dbi->execute($sql, $param, table => 'book');
88

            
89
=item 3. 選択的な検索条件
90

            
91
生のDBIを利用しているとき一番たいへんなのは選択的な検索条件を作成したいときです。
92

            
93
たとえば、検索条件にtitleとauthorが指定された場合は次のSQLを
94

            
95
    select * from book where title = ? and author = ?;
96

            
97
titleだけの場合は次のSQLを
98

            
99
    select * from book where title = ?;
100
    
101
authorだけの場合は次のSQLを発行した場合を考えましょう。
102

            
103
    select * from book where author = ?;
104

            
105
これはとても大変な作業なので、通常はL<SQL::Abstract>を動的に生成してくれる
106
モジュールを利用することになります。
107

            
108
L<DBIx::Custom>はさらに簡単で便利な方法を用意しています。
109

            
110
    my $where = $dbi->where;
111
    $where->param({title => 'Perl'});
112
    $where->clause(
113
        ['and', '{= title}', {'= author'}]
114
    );
115

            
116
    my $sql = "select * from book $where";
117

            
118
詳しい説明は後ほど行いますが、上記のように記述すれば、
119
L<DBIx::Custom>では選択的な検索条件を持つWhere句を生成することができます。
120
検索条件が入れ子になった構造やorについても対応しています。
121

            
122
=item 4. 挿入、更新、削除、選択を行うためのメソッド
123

            
124
L<DBIx::Custom>ではSQLをさらに簡単に実行するための
125
メソッドも提供しています。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
126
C<insert()>, C<update()>, C<delete()>,C<select()>などの
updated document
Yuki Kimoto authored on 2011-01-20
127
シュガーメソッドを使って、挿入、更新、削除、選択という操作を行うことが
128
できます。
129

            
130
    my $param = {title => 'Perl', author => 'Ken'};
131
    $dbi->insert(table => 'book', param => $param);
132

            
133
=item 5. テーブル単位の操作の登録
134

            
135
テーブルに対して操作を登録することができます。これによって
136
テーブル名を繰り返し指定する必要がなくなり、ソースコードの
137
見通しが良くなります。
138

            
139
    $dbi->talbe('book',
140
        list => sub {
141
            ...
142
        },
143
        list_somethin => sub {
144
            
145
        }
146
    );
147

            
148
登録したメソッドはそのまま利用することができます。
149

            
150
    $dbi->table('book')->list;
added experimental expand me...
yuki-kimoto authored on 2010-10-20
151

            
updated document
Yuki Kimoto authored on 2011-01-20
152
通常O/Rマッパはテーブルに対応するクラスを作成しなければ
153
ならないことが多いですが、L<DBIx::Custom>ではこの作業を簡便に
154
しており、上記のように登録することができます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
155

            
updated document
Yuki Kimoto authored on 2011-01-20
156
=back
157

            
158
L<DBIx::Custom>はL<DBI>を補うとても便利なモジュールです。
159
興味をもたれた方は、この後で詳しい解説を行いますので、
160
ご覧になってみてください。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
161

            
162
=head2 1. データベースへの接続
163

            
updated document
Yuki Kimoto authored on 2011-01-23
164
まずL<DBIx::Custom>を読み込みます。
165

            
166
    use DBIx::Custom;
167

            
added experimental expand me...
yuki-kimoto authored on 2010-10-20
168
L<DBIx::Custom>オブジェクトを生成し、データベースに接続するには
169
C<connect()>メソッドを使用します。
170

            
updated document
Yuki Kimoto authored on 2011-01-23
171
    my $dbi = DBIx::Custom->connect(
172
        data_source => "dbi:mysql:database=dbname",
173
        user => 'ken',
174
        password => '!LFKD%$&',
175
        dbi_options => {mysql_enable_utf8 => 1}
176
    );
added experimental expand me...
yuki-kimoto authored on 2010-10-20
177

            
updated document
Yuki Kimoto authored on 2011-01-23
178
C<data_source>はデータベースシステムに応じたフォーマットで
179
指定する必要があります。以下にデータベースごとのフォーマット
180
方法のサンプルを掲載しておきます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
181

            
updated document
Yuki Kimoto authored on 2011-01-23
182
B<MySQL>
added experimental expand me...
yuki-kimoto authored on 2010-10-20
183

            
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
184
    "dbi:mysql:database=$database"
185
    "dbi:mysql:database=$database;host=$hostname;port=$port"
added experimental expand me...
yuki-kimoto authored on 2010-10-20
186

            
updated document
Yuki Kimoto authored on 2011-01-23
187
B<SQLite>
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
188

            
189
    "dbi:SQLite:dbname=$database"
190
    "dbi:SQLite:dbname=:memory:"
191

            
updated document
Yuki Kimoto authored on 2011-01-23
192
B<PostgreSQL>
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
193

            
194
    "dbi:Pg:dbname=$dbname"
195

            
updated document
Yuki Kimoto authored on 2011-01-23
196
B<Oracle>
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
197

            
198
    "dbi:Oracle:$dbname"
199
    "dbi:Oracle:host=$host;sid=$sid"
200

            
updated document
Yuki Kimoto authored on 2011-01-23
201
B<ODBC(Microsoft Access)>
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
202

            
203
    "dbi:ODBC:driver=Microsoft Access Driver (*.mdb);dbq=hoge.mdb"
204

            
updated document
Yuki Kimoto authored on 2011-01-23
205
B<ODBC(SQL Server)>
deprecated DBIx::Custom::MyS...
root authored on 2010-11-26
206

            
207
   "dbi:ODBC:driver={SQL Server};Server=(local);database=test;Trusted_Connection=yes;AutoTranslate=No;"
added experimental expand me...
yuki-kimoto authored on 2010-10-20
208

            
updated document
Yuki Kimoto authored on 2011-01-23
209
また認証が求められる場合は、C<user>とC<password>ユーザ名と
210
パスワードを指定する必要があります。
211

            
added experimental expand me...
yuki-kimoto authored on 2010-10-20
212
L<DBIx::Custom>はL<DBI>のラッパです。
updated document
Yuki Kimoto authored on 2011-01-23
213
L<DBI>のデータベースハンドルはC<dbh>で取得することができます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
214

            
215
    my $dbh = $dbi->dbh;
216

            
updated document
Yuki Kimoto authored on 2011-01-23
217
L<DBIx::Custom>ではデータベースハンドル属性にはデフォルトで次のものが設定されます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
218
    
219
    $dbi->dbh->{RaiseError} = 1;
220
    $dbi->dbh->{PrintError} = 0;
221
    $dbi->dbh->{AutoCommit} = 1;
222

            
223
この設定を行っているので、致命的なエラーが起こると、
224
例外が発生しプログラムは終了します。
225
またクエリが発行されると自動的にコミットされます。
226

            
updated document
Yuki Kimoto authored on 2011-01-23
227
=head2 2. 挿入、更新、削除、選択のためのメソッド
added experimental expand me...
yuki-kimoto authored on 2010-10-20
228

            
229
L<DBIx::Custom>は、
230
C<insert()>、C<update()>、C<delete()>、C<select()>
updated document
Yuki Kimoto authored on 2011-01-23
231
のような挿入、更新、削除、選択を行うためのメソッドを持っています。
232
簡単なことをを行うのであれば、SQLを自分で記述する必要がありません。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
233

            
234
=head3 C<insert()>
235

            
updated document
Yuki Kimoto authored on 2011-01-23
236
データベースにデータを挿入するにはC<insert()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
237

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
238
    $dbi->insert(table  => 'book',
added experimental expand me...
yuki-kimoto authored on 2010-10-20
239
                 param  => {title => 'Perl', author => 'Ken'});
240

            
updated document
Yuki Kimoto authored on 2011-01-23
241
C<table>にはテーブル名、C<param>には挿入したいデータを指定します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
242

            
updated document
Yuki Kimoto authored on 2011-01-23
243
次のSQLが発行されます。
244

            
245
    insert into (title, author) values (?, ?);
added experimental expand me...
yuki-kimoto authored on 2010-10-20
246

            
247
=head3 C<update()>
248

            
updated document
Yuki Kimoto authored on 2011-01-23
249
データベースのデータを更新するには、C<update()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
250

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
251
    $dbi->update(table  => 'book', 
added experimental expand me...
yuki-kimoto authored on 2010-10-20
252
                 param  => {title => 'Perl', author => 'Ken'}, 
253
                 where  => {id => 5});
254

            
updated document
Yuki Kimoto authored on 2011-01-23
255
C<table>にはテーブル名、C<param>には挿入したいデータ、C<where>には
256
条件を指定します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
257

            
updated document
Yuki Kimoto authored on 2011-01-23
258
次のSQLが発行されます。
259

            
260
    update book set title = ?, author = ?;
added experimental expand me...
yuki-kimoto authored on 2010-10-20
261

            
262
C<update>メソッドは安全のため
263
where句のないSQLを発行することを許可していません。
264
もしすべての行を更新したい場合は
updated document
Yuki Kimoto authored on 2011-01-23
265
C<update_all()>を使用してください。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
266

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
267
    $dbi->update_all(table  => 'book', 
added experimental expand me...
yuki-kimoto authored on 2010-10-20
268
                     param  => {title => 'Perl', author => 'Ken'});
269

            
270
=head3 C<delete()>
271

            
updated document
Yuki Kimoto authored on 2011-01-23
272
データベースのデータを1件削除するには、C<delete()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
273

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
274
    $dbi->delete(table  => 'book',
added experimental expand me...
yuki-kimoto authored on 2010-10-20
275
                 where  => {author => 'Ken'});
276

            
updated document
Yuki Kimoto authored on 2011-01-23
277
C<table>にはテーブル名、C<where>には条件を指定します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
278

            
updated document
Yuki Kimoto authored on 2011-01-23
279
次のSQLが発行されます。
280

            
281
    delete from book where id = ?;
added experimental expand me...
yuki-kimoto authored on 2010-10-20
282

            
283
C<delete>メソッドは安全のため
284
where句のないSQLを発行することを許可していません。
285
もしすべての行を削除したい場合は
updated document
Yuki Kimoto authored on 2011-01-23
286
C<delete_all()>を使用してください。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
287

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
288
    $dbi->delete_all(table  => 'book');
added experimental expand me...
yuki-kimoto authored on 2010-10-20
289

            
290
=head3 C<select()>
291

            
updated document
Yuki Kimoto authored on 2011-01-23
292
行を選択するにはC<select()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
293

            
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
294
    my $result = $dbi->select(table => 'book');
added experimental expand me...
yuki-kimoto authored on 2010-10-20
295

            
updated document
Yuki Kimoto authored on 2011-01-23
296
C<table>だけを指定して、他の条件を指定しない場合は次のSQLが発行されます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
297

            
updated document
Yuki Kimoto authored on 2011-01-23
298
    select * from book;
added experimental expand me...
yuki-kimoto authored on 2010-10-20
299

            
300
C<select()>メソッドの戻り値はL<DBIx::Custom::Result>
updated document
Yuki Kimoto authored on 2011-01-23
301
オブジェクトです。行をフェッチするにはC<fetch()>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
302

            
303
    while (my $row = $result->fetch) {
304
        my $title  = $row->[0];
305
        my $author = $row->[1];
306
    }
307

            
updated document
Yuki Kimoto authored on 2011-01-23
308
L<DBIx::Custom::Result>についてはこの後L<3. 行のフェッチ/"3. 行のフェッチ">で詳しく扱います。
309

            
310
さまざまなC<select()>の使い方を見ていきましょう。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
311
次のC<select>は行の名前とwhere句を指定したものです。
312

            
313
    my $result = $dbi->select(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
314
        table  => 'book',
updated document
Yuki Kimoto authored on 2011-01-23
315
        column => ['author',  'title'],
added experimental expand me...
yuki-kimoto authored on 2010-10-20
316
        where  => {author => 'Ken'}
317
    );
318

            
updated document
Yuki Kimoto authored on 2011-01-23
319
C<column>には列名を、C<where>には条件を指定することができます。
320
次のSQLが発行されます。
321

            
322
    select author, title from book where author = ?;
added experimental expand me...
yuki-kimoto authored on 2010-10-20
323

            
updated document
Yuki Kimoto authored on 2011-01-23
324
テーブルを結合したい場合ははC<relation>にテーブルの
325
関係を記述します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
326

            
327
    my $result = $dbi->select(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
328
        table    => ['book', 'rental'],
updated document
Yuki Kimoto authored on 2011-01-23
329
        where    => {book.name => 'Perl'},
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
330
        relation => {'book.id' => 'rental.book_id'}
added experimental expand me...
yuki-kimoto authored on 2010-10-20
331
    );
332

            
updated document
Yuki Kimoto authored on 2011-01-23
333
bookテーブルのid列とrentalテーブルのbook_idが関連付けられます。
334
次のSQLが発行されます。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
335

            
updated document
Yuki Kimoto authored on 2011-01-23
336
    select * from book, rental where book.name = ? and book.id = rental.book_id;
added experimental expand me...
yuki-kimoto authored on 2010-10-20
337

            
updated document
Yuki Kimoto authored on 2011-01-23
338
SQL文の末尾に文字列を追加したい場合は<append>を使用します。
added experimental expand me...
yuki-kimoto authored on 2010-10-20
339

            
340
    my $result = $dbi->select(
remove DBIx::Custom::Model
Yuki Kimoto authored on 2011-01-12
341
        table  => 'book',
added experimental expand me...
yuki-kimoto authored on 2010-10-20
342
        where  => {author => 'Ken'},
updated document
Yuki Kimoto authored on 2011-01-23
343
        append => 'for update',
added experimental expand me...
yuki-kimoto authored on 2010-10-20
344
    );
345

            
updated document
Yuki Kimoto authored on 2011-01-23
346
次のSQLが発行されます。
updated document
Yuki Kimoto authored on 2011-01-20
347

            
updated document
Yuki Kimoto authored on 2011-01-23
348
    select * book where author = ? for update;
updated document
Yuki Kimoto authored on 2011-01-20
349

            
updated document
Yuki Kimoto authored on 2011-01-23
350
またC<append>は、C<select>だけでなくC<insert()>、C<update()>、C<update_all()>
351
C<delete()>、C<delete_all()>、C<select()>で使用することもできます。
updated document
Yuki Kimoto authored on 2011-01-20
352

            
353
=head2 3. 行のフェッチ
354

            
updated document
Yuki Kimoto authored on 2011-01-23
355
C<select()>メソッドの戻り値はL<DBIx::Custom::Result>オブジェクトです。
356
L<DBIx::Custom::Result>には行をフェッチするためのさまざまなメソッドが
updated document
Yuki Kimoto authored on 2011-01-20
357
用意されています。
358

            
359
=head3 C<fetch>
360

            
updated document
Yuki Kimoto authored on 2011-01-23
361
一行フェッチして配列のリファレンスに格納するにはC<fetch()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
362

            
363
    while (my $row = $result->fetch) {
updated document
Yuki Kimoto authored on 2011-01-23
364
        my $title  = $row->[0];
365
        my $author = $row->[1];
updated document
Yuki Kimoto authored on 2011-01-20
366
    }
367

            
updated document
Yuki Kimoto authored on 2011-01-23
368
whileループを使って、すべての行を取得することができます。
369

            
updated document
Yuki Kimoto authored on 2011-01-20
370
=head3 C<fetch_first>
371

            
updated document
Yuki Kimoto authored on 2011-01-23
372
一行だけフェッチして配列のリファレンスに格納するにはC<fetch_first()>
373
を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
374

            
375
    my $row = $result->fetch_first;
376

            
updated document
Yuki Kimoto authored on 2011-01-23
377
一行のフェッチが終わった後はそれ以上フェッチできなくなります。
378
内部的には1行のフェッチが終わった後に
379
ステートメントハンドルのC<finish()>が実行されます。
updated document
Yuki Kimoto authored on 2011-01-20
380

            
381
=head3 C<fetch_multi>
382

            
updated document
Yuki Kimoto authored on 2011-01-23
383
複数行をフェッチして配列のリファレンスを要素に持つ
384
配列のリファレンスに格納するにはC<fetch_multi()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
385

            
updated document
Yuki Kimoto authored on 2011-01-23
386
    while (my $rows = $result->fetch_multi(2)) {
387
        my $title0   = $rows->[0][0];
388
        my $author0  = $rows->[0][1];
389
        
390
        my $title1   = $rows->[1][0];
391
        my $author1  = $rows->[1][1];
updated document
Yuki Kimoto authored on 2011-01-20
392
    }
393

            
updated document
Yuki Kimoto authored on 2011-01-23
394
引数には取り出したい行数を指定します。
395

            
396
指定した行を格納した次のようなデータを取得できます。
397

            
398
    [
399
        ['Perl', 'Ken'],
400
        ['Ruby', 'Mark']
401
    ]
402

            
updated document
Yuki Kimoto authored on 2011-01-20
403
=head3 C<fetch_all>
404

            
updated document
Yuki Kimoto authored on 2011-01-23
405
すべての行をフェッチして配列のリファレンスを要素に持つ
406
配列のリファレンスに格納するにはC<fetch_all()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
407

            
408
    my $rows = $result->fetch_all;
409

            
updated document
Yuki Kimoto authored on 2011-01-23
410
すべての行を格納した次のようなデータを取得できます。
411

            
412
    [
413
        ['Perl', 'Ken'],
414
        ['Ruby', 'Mark']
415
    ]
416

            
updated document
Yuki Kimoto authored on 2011-01-20
417
=head3 C<fetch_hash>
418

            
updated document
Yuki Kimoto authored on 2011-01-23
419
一行フェッチしてハッシュのリファレンスに格納するにはC<fetch_hash()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
420

            
421
    while (my $row = $result->fetch_hash) {
422
        my $title  = $row->{title};
423
        my $author = $row->{author};
424
    }
425

            
426
=head3 C<fetch_hash_first>
427

            
updated document
Yuki Kimoto authored on 2011-01-23
428
一行だけフェッチしてハッシュのリファレンスに格納するには
429
C<fetch_hash_first()>を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
430

            
431
    my $row = $result->fetch_hash_first;
432

            
updated document
Yuki Kimoto authored on 2011-01-23
433
一行のフェッチが終わった後はそれ以上フェッチできなくなります。
434
内部的には1行のフェッチが終わった後に
435
ステートメントハンドルのC<finish()>が実行されます。
updated document
Yuki Kimoto authored on 2011-01-20
436

            
437
=head3 C<fetch_hash_multi>
438

            
updated document
Yuki Kimoto authored on 2011-01-23
439
複数行をフェッチしてハッシュのリファレンスを要素に持つ
440
配列のリファレンスに格納するにはC<fetch_hash_multi()>
441
を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
442

            
443
    while (my $rows = $result->fetch_hash_multi(5)) {
updated document
Yuki Kimoto authored on 2011-01-23
444
        my $title0   = $rows->[0]{title};
445
        my $author0  = $rows->[0]{author};
446
        my $title1  = $rows->[1]{title};
447
        my $author1 = $rows->[1]{author};
updated document
Yuki Kimoto authored on 2011-01-20
448
    }
449

            
updated document
Yuki Kimoto authored on 2011-01-23
450
引数には取り出したい行数を指定します。
451

            
452
指定した行を格納した次のようなデータを取得できます。
453

            
454
    [
455
        {title => 'Perl', author => 'Ken'},
456
        {title => 'Ruby', author => 'Mark'}
457
    ]
458

            
updated document
Yuki Kimoto authored on 2011-01-20
459
=head3 C<fetch_all>
460

            
updated document
Yuki Kimoto authored on 2011-01-23
461
すべての行をフェッチしてハッシュのリファレンスを要素に持つ
462
配列のリファレンスに格納するにはC<fetch_hash_all()>
463
を使用します。
updated document
Yuki Kimoto authored on 2011-01-20
464

            
465
    my $rows = $result->fetch_hash_all;
466

            
updated document
Yuki Kimoto authored on 2011-01-23
467
すべての行を格納した次のようなデータを取得できます。
468

            
469
    [
470
        {title => 'Perl', author => 'Ken'},
471
        {title => 'Ruby', author => 'Mark'}
472
    ]
473

            
474
=head3 sth
475

            
476
ステートメントハンドルに直接アクセスしたい場合は
477
<sth>で取得することができます。
updated document
Yuki Kimoto authored on 2011-01-20
478

            
479
    my $sth = $result->sth;
480

            
updated document
Yuki Kimoto authored on 2011-01-23
481
フェッチのパフォーマンスが用件を満たさないときには、
482
ステートメントハンドルから
483
利用できる速度の速いメソッドを利用することができます。
484

            
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
485
=head2 4. フィルタリング
486

            
487
データベースにデータを登録するときやデータベースからデータを取得する
488
ときに自動的に値の変換を行いたい場合が多いと思います。
489
たとえば、日付を表現する列の場合は、
490
データベースに登録する場合はL<Time::Piece>オブジェクトから
491
データベースの日付のフォーマットに、
492
データベースからデータを取得するときは、その逆を行えると便利です。
493

            
494
=head3 フィルタの登録
495

            
496
フィルタを登録するにはC<register_filter()>を使用します。
497

            
498
    $dbi->register_filter(
499
        # Time::Piece object to DATE format
500
        tp_to_date => sub {
501
            my $date = shift;
502

            
503
            return '0000-00-00' unless $tp;
504
            return $tp->strftime('%Y-%m-%d');
505
        },
506
        
507
        # DATE to Time::Piece object
508
        date_to_tp => sub {
509
            my $date = shift;
510

            
511
            return if $date eq '0000-00-00';
512
            return Time::Piece->strptime($date, '%Y-%m-%d');
513
        },
514
    );
515

            
516
登録したフィルタはC<apply_filter()>などで利用することができます。
517

            
518
=head3 フィルタの適用
519

            
520
作成したフィルタを適用するには、C<apply_filter()>を使用します。
521

            
522
    $dbi->apply_filter('book',
523
        issue_date => {out => 'tp_to_date', in => 'date_to_tp'},
524
        first_issue_date => {out => 'tp_to_date', in => 'date_to_tp'}
525
    );
526

            
527
第一引数はテーブル名です。第二引数以降は、列名とフィルタルールのペアを記述します。
528
フィルタルールのoutには、データベースにデータを送信するときに適用するフィルタを、
529
フィルタルールのinには、データベースからデータを取得するときに適用するフィルタを
530
記述します。outがデータベースに送信する方向、inがデータベースから取り出す方向です。
531
フィルタには、C<register_filter>で登録したフィルタ名の他に、コードリファレンスを
532
指定することもできます。
533

            
534
    issue_date => {out => sub { ... }, in => sub { ... }}
535

            
536
適用されたフィルタはC<insert()>、C<update()>、C<update_all()>、C<delete()>、
537
C<delete_all()>、C<select()>で有効になります。
538

            
539
    my $tp = Time::Piece->strptime('2010/10/14', '%Y/%m/%d');
540
    my $result = $dbi->select(table => 'book', where => {issu_date => $tp});
541

            
542
データベースにデータが送信されるときに、L<Time::Piece>オブジェクトは
543
データベースの日付のフォーマット「2010-10-14」に変換されます。
544

            
545
また逆にデータをフェッチするときには、データベースの日付のフォーマットは
546
タイムピースオブジェクトに変換されます。
547

            
548
    my $row = $resutl->fetch_hash_first;
549
    my $tp = $row->{issue_date};
550

            
551
このような自動的に実行されるフィルタを登録できることがL<DBIx::Custom>の
552
特徴のひとつです。
553

            
554
=head3 個別にフィルタを適用する
555

            
556
C<apply_filter()>を使って最初にすべてのテーブルの列について
557
フィルタを定義しておくこともできますが、
558
さらに個別にフィルタを適用することもできます。
559
個別のフィルタはC<apply_filter()>で適用したフィルタを上書きます。
560

            
561
行をフェッチするときに個別にフィルタを適用するには、
562
C<DBIx::Custom::Result>クラスのC<filter>メソッドを使用します。
563

            
564
    $result->filter(issue_date => 'date_to_tp', first_issue_date => 'date_to_tp');
565

            
566
これは、C<apply_filter()>のフィルタルールのinで定義されたフィルタを上書きます。
567

            
568
=head2 5. タグ
updated document
Yuki Kimoto authored on 2011-01-20
569

            
570
L<DBIx::Custom>はハッシュパラメタバインドを提供します。
571

            
572
まず最初にL<DBI>による通常のパラメタバインドをご覧ください。
573

            
574
    use DBI;
575
    my $dbh = DBI->connect(...);
576
    my $sth = $dbh->prepare(
577
        "select * from book where author = ? and title like ?;"
578
    );
579
    $sth->execute('Ken', '%Perl%');
580

            
581
これはデータベースシステムがSQLをキャッシュすることができ、
582
パラメータは自動的にクォートされるので、
583
パフォーマンス面でも、セキュリティ面でも
584
とても良い方法です。
585

            
586

            
587
L<DBIx::Custom>はこれを改善して、ハッシュで
588
パラメタを指定できるようにしました。
589

            
590
    my $result = $dbi->execute(
591
        "select * from book where {= author} and {like title};"
592
        param => {author => 'Ken', title => '%Perl%'}
593
    );
594

            
595
C<{= author}>とC<{like title}>はタグと呼ばれます。
596
タグは内部ではプレースホルダを含む文字列に置き換えられます。
597

            
598
    select * from book where {= author} and {like title}
599

            
600
という文は以下のSQLに置き換えられます。
601

            
602
    select * from book where author = ? and title like ?;
603

            
604
このようにタグを使ってSQL文を表現するのがL<DBIx::Custom>の
605
特徴です。以下のタグが利用可能です。
606

            
607
    [TAG]                       [REPLACED]
608
    {? NAME}               ->   ?
609
    {= NAME}               ->   NAME = ?
610
    {<> NAME}              ->   NAME <> ?
611
    
612
    {< NAME}               ->   NAME < ?
613
    {> NAME}               ->   NAME > ?
614
    {>= NAME}              ->   NAME >= ?
615
    {<= NAME}              ->   NAME <= ?
616
    
617
    {like NAME}            ->   NAME like ?
618
    {in NAME COUNT}        ->   NAME in [?, ?, ..]
619
    
620
    {insert_param NAME1 NAME2}   ->   (NAME1, NAME2) values (?, ?)
621
    {update_param NAME1 NAME2}   ->   set NAME1 = ?, NAME2 = ?
622

            
623
これらの変換はL<DBIx::Custom::QueryBuilder>によって行われます。
624

            
625
C<{>とC<}>は予約語です。これらの文字を使いたい場合は
626
「\」を使ってエスケープする必要があります。
627
'\'はPerlのエスケープ文字なので、
628
エスケープするためには'\\'と書く必要があることに注意
629
してください。
630

            
631
    'select * from book \\{ something statement \\}'
632

            
633
=head2 6. パフォーマンスの改善
634

            
635
=head3 シュガーメソッドを使わない
636

            
637
もしC<insert()>メソッドを使用してインサートを実行した場合、
638
必要なパフォーマンスを得られない場合があるかもしれません。
639
C<insert()>メソッドは、SQL文とステートメントハンドルを
640
毎回作成するためすこし遅いです。
641

            
642
そのような場合は、C<create_query()>メソッドによって
643
クエリを用意しておくことができます。
644
    
645
    my $query = $dbi->create_query(
646
        "insert into book {insert_param title author};"
647
    );
648

            
649
戻り値はL<DBIx::Custom::Query>オブジェクトです。
650
このオブジェクトはSQL文とパラメータバインド時の列名を
651
保持しています。またステートメントハンドルも保持しています。
652

            
653
    {
654
        sql     => 'insert into book (title, author) values (?, ?);',
655
        columns => ['title', 'author'],
656
        sth     => $sth
657
    }
658

            
659
クエリオブジェクトを使って繰り返し実行するには次のようにします。
660
    
661
    my $inputs = [
662
        {title => 'Perl',      author => 'Ken'},
663
        {title => 'Good days', author => 'Mike'}
664
    ];
665
    
666
    foreach my $input (@$inputs) {
667
        $dbi->execute($query, $input);
668
    }
669

            
670
C<execute>メソッドの第一引数にクエリオブジェトを渡すことができます。
671
これはC<insert()>メソッドよりも高速です。
672

            
673
=head2 7. その他の機能
674

            
675
=head3 トランザクション
676

            
677
トランザクションを便利に利用するために、
678
C<begin_work()>、C<commit()>、C<rollback()>
679
という三つのメソッドが容易されています。
680
これはL<DBI>の同名のメソッドと同じ機能を持ちます。
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
681
fc
updated document
Yuki Kimoto authored on 2011-01-20
682
    $dbi->begin_work;
683
    
684
    eval {
685
        $dbi->update(...);
686
        $dbi->update(...);
687
    };
688
    
689
    if ($@) {
690
        $dbi->rollback;
691
    }
692
    else {
693
        $dbi->commit;
694
    }
695

            
696
=head3 selectメソッドの結果クラスの変更
697

            
698
必要ならばC<select()>メソッドの結果クラスを変更することができます。
699

            
700
    package Your::Result;
701
    use base 'DBIx::Custom::Result';
702
    
703
    sub some_method { ... }
704

            
705
    1;
706
    
707
    package main;
708
    
709
    use Your::Result;
710
    
711
    my $dbi = DBIx::Custom->connect(...);
712
    $dbi->result_class('Your::Result');
713

            
714
=head3 L<DBIx::Custom::QueryBuilder>の機能の拡張
715

            
716
新しいタグが欲しい場合はL<DBIx::Custom::QueryBuilder>の機能を拡張
717
することができます。
718

            
719
    my $dbi = DBIx::Custom->connect(...);
720
    $dbi->query_builder->register_tag_processor(
721
        name => sub {
722
           ...
723
        }
724
    );
725

            
726
=head3 ヘルパーメソッドの登録
727

            
728
ヘルパーメソッドを登録することができます。
729

            
730
    $dbi->helper(
731
        update_or_insert => sub {
732
            my $self = shift;
733
            # do something
734
        },
735
        find_or_create   => sub {
736
            my $self = shift;
737
            # do something
738
        }
739
    );
740

            
741
<helper()>メソッドで登録したメソッドは
742
L<DBIx::Custom>オブジェクトから直接呼び出すことができます。
743

            
744
    $dbi->update_or_insert;
745
    $dbi->find_or_create;
746

            
renamed dbi_options to dbi_o...
Yuki Kimoto authored on 2011-01-23
747
=head3 ユーティリティメソッド
updated document
Yuki Kimoto authored on 2011-01-20
748

            
749
C<expand>メソッドを使用すると次のようなハッシュに含まれる
750
テーブル名と列名を結合することができます。
751

            
752
    my %expanded = $dbi->expand(\%source);
753

            
754
以下のハッシュ
755

            
756
    {book => {title => 'Perl', author => 'Ken'}}
757

            
758
は次のように展開されます。
759

            
760
    ('book.title' => 'Perl', 'book.author' => 'Ken')
761

            
762
これはテーブル名を含むselect文で利用すると便利です。
763

            
764
    my $param = {title => 'Perl', author => '%Ken%'};
765
    $dbi->execute(
766
        'select * from book where {= book.title} && {like book.author};',
767
        param => {$dbi->expand({book => $param})}
768
    );
769

            
770
=cut