6. O/Rマッパーだと開発が抜群に早くなる
複数データ群をリレーションつけて登録する場合のコード比較
DBI Teng
use DBI; #Teng-0.14_05
use DBI;
my @data_set = ( use Teng;
[26,'hiro'], use Teng::Schema::Loader;
[27,'bane'],
); my @data_set = (
[26,'hiro'],
my $dbh = DBI->connect("DBI:mysql:db_name;", "root", "pass",{ [27,'bane'],
AutoCommit => 0, );
});
my $dbh = DBI->connect("DBI:mysql:db_name;", "root", "pass",);
for my $data (@data_set) {
my ($age,$name) = @$data; my $teng = Teng::Schema::Loader->load(
dbh => $dbh,
my ($age_id) = $dbh->selectrow_array(q{ namespace => 'MyAPP::DB',
SELECT id FROM age WHERE age = ? );
},undef,$age); $teng->load_plugin('FindOrCreate');
unless ($age_id) { my $txn = $teng->txn_scope;
my $sth = $dbh->prepare(q{ for my $data (@data_set) {
INSERT INTO age (age) VALUES ( ? ) my ($age,$name) = @$data;
});
$sth->execute($age); my $row = $teng->find_or_create('age',{ age => $age });
#mysql限定 $teng->insert('user', { age_id => $row->id, name => $name });
$age_id = $dbh->last_insert_id(undef, undef, 'age', 'id'); }
} $txn->commit;
my $sth = $dbh->prepare(q{
INSERT INTO user (age_id, name) VALUES (?, ?)
});
$sth->execute($age_id, $name);
} 20行 7行
$dbh->do('COMMIT'); 5
9. Tengのnew(オブジェクトの作り方)
Teng::Schema::Loaderというのを使うと楽
#Teng-0.14_05 とりあえずメソッド化 #Teng-0.14_05 永続化
use strict; package MyDB;
use warnings; use strict; use warnings; use utf8;
use DBI; use DBI;
use utf8; use Teng;
use Teng; use Teng::Schema::Loader;
use Teng::Schema::Loader;
our $TENG;
sub teng { sub teng {
my $dbh = DBI->connect("dbi:SQLite:./users.db", '', '', +{ $TENG ||= do {
Callbacks => { my $dbh = DBI->connect("dbi:SQLite:./users.db", '', '', +{
connected => sub { Callbacks => {
my $conn = shift; connected => sub {
$conn->do(<<EOF); #テーブルの構造をココに書く my $conn = shift;
CREATE TABLE user ( $conn->do(<<EOF);
id INTEGER PRIMARY KEY, CREATE TABLE user (
user_name varchar(10), id INTEGER PRIMARY KEY,
sex varchar(10) default 'male', user_name varchar(10),
age INTEGER default 20, sex varchar(10) default 'male',
); age INTEGER default 20,
EOF );
return; EOF
}, return;
}, },
sqlite_unicode => 1,#MySQLは、mysql_enable_utf8 => 1 , },
}); sqlite_unicode => 1,
});
my $teng = Teng::Schema::Loader->load(
dbh => $dbh, Teng::Schema::Loader->load(
namespace => 'MyDB::Schema' dbh => $dbh,
); namespace => 'MyDB::Schema'
} );
}
}
1; 8
10. SELECT
SQL文の書けるsearch_by_sqlメソッドを使う
複数行の取り出し 1行だけの取り出し
use MyDB; use MyDB;
my @users = MyDB->teng->search_by_sql( my $row = MyDB->teng->search_by_sql(
q{#SQL文が普通にかける q{ SELECT * FROM user WHERE user_name = ? },
SELECT ['hirobanex']
id, user_name )->first;
FROM user
WHERE
sex = ? AND age > ?
},
['male',20]#bind値は配列のリファレンスで設定
)->all;
#Rowオブジェクトなるものがいる
for my $row (@users) {
#カラムはRowオブジェクトに
#カラム名でメソッド呼び出し
warn $row->id;
warn $row->user_name;
}
9
11. INSERT、UPDATE、DELETE
SQL文の書けるdoメソッドを使う
INSERT UPDATE
use MyDB; MyDB->teng->do(q{
UPDATE user SET
MyDB->teng->do(q{ user_name = ?
INSERT INTO user ( ,age = ?
user_name,sex,age WHERE
) VALUES ( user_name = ?
?,?,? },undef,('bane','27','hirobanex'));
);
},undef,('hirobanex','male','26')); DELETE
# errorハンドリングはTengのほうで
やってくれている
MyDB->teng->do(q{
DELETE user WHERE user_name = ?
},undef,('bane'));
10
12. トランザクション
囲うだけ
use MyDB;
my $teng = MyDB->teng;
my $txn = $teng->txn_scope;
for my $user_name ('hiro','bane','ytnobody') {
$teng->do(q{
INSERT INTO user (user_name) VALUES (?);
},umdef,$user_name );
}
$txn->commit;
hachioji.pm 11