Click here to load reader
Upload
ryuichi-tanaka
View
1.169
Download
6
Embed Size (px)
DESCRIPTION
Web技術勉強会 第25回
Citation preview
WEB技術勉強会技術勉強会技術勉強会技術勉強会 第第第第25回回回回RYUICHI TANAKA.
DBIx::ClassととととDBIx::Class::Schema::Loaderでででで楽楽楽楽々々々々O/Rマッピングマッピングマッピングマッピング
O/Rマッピングとは
�オブジェクトとRDBのレコードを対応付けることができる技術。
� SQLを書かなくともDBアクセス� SQLを書かなくともDBアクセスができる。
代表的ORマッパー
� Perl� DBIx::Class(通称DBIC)
� Class::DBIx(現在は開発停止)
� Java� Java� Hibernate(JPA標準)
� Ruby(Rails)� ActiveRecord
� PHP� Propel( synfonyで使用)
ORマッピングのなにがよいのか
� SQLを書かなくて済む
�コードがすっきりする
� DB構成が変わったときの保守� DB構成が変わったときの保守が比較的楽
逆にORマッピングのだめなところ
�処理が遅くなる
�複雑なSQLは厳しい
つまり、ORマッピングとは
�簡単なSQLですむときに使うと幸せになれる
�それ以外のときは生SQLを実行�それ以外のときは生SQLを実行しないと幸せになれない
DBIx::Class
� Perlで一番メジャーなORマッパー
� Class::DBIの後継的存在� Class::DBIの後継的存在
� Catalystで標準使用されている
DBIx::Class::Schema::Loader
� DBIx::Classで使用するSchema
ファイルを自動生成する
Schemaファイルとは
�テーブルの各カラムのデータ型をオブジェクトとして定義する
� DBIx::Classを継承して定義する� DBIx::Classを継承して定義する
インストール
� CPAN経由で
�依存モジュールがすごい数インストールされるストールされる
Schemaファイルの生成
� ワンライナーの場合$ perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib -
e 'make_schema_at "Hoge::Schema", {relationships => 1, debug => 1},
["dbi:mysql:hoge","user","password"]'
ただし、今回はワンライナーは使用しない。
ソースファイルにして拡張性を高めて、
Eclipseから実行するため。
Schemaファイルの生成
make_schema.pl
を実行する①
スキーマファイルが自動生成される
②
Schemaファイルの生成(コード)#!/usr/bin/perluse strict;use warnings;use FindBin::libs qw{ export base=syscommon };use MyLibs::Common::DB::Config;use DBIx::Class::Schema::Loader qw( make_schema_at );
# スキーマファイルの出力先my $dump_directory = 'C:/workspace/syscommon';
# データベース名を指定# データベース名を指定my $dbname = "tclipers";
my ($conf_obj, $db_conf);
$conf_obj = MyLibs::Common::DB::Config->new();$conf_obj->use_db("mysql");$db_conf = $conf_obj->get_db_config();
make_schema_at('MyLibs::Common::DB::Schema',{relationships => 1, debug => 1, dump_directory => $dump_directory},["dbi:$db_conf->{dbms}:dbname=$dbname;host=$db_conf->{host}", $db_conf->{user}, $db_conf->{pass}]
);
生成されたSchemaファイルpackage MyLibs::Common::DB::Schema::Tclipers;
use strict;use warnings;
use base 'DBIx::Class';
__PACKAGE__->load_components("Core");__PACKAGE__->table("tclipers");__PACKAGE__->add_columns("id","id",{ data_type => "INT", default_value => undef, is_nullable => 0, size => 11 },…
);__PACKAGE__->set_primary_key("id");__PACKAGE__->add_unique_constraint("url_hash_index", ["url_hash"]);
# Created by DBIx::Class::Schema::Loader v0.04006 @ 2009-07-12 01:49:00# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:YCPFZVg0EvGhZEbLwsh2AA
# You can replace this text with custom content, and it will be preserved on regeneration1;
実際にORマッピングしてみる
� Schemaファイル生成時に同時に作られる「Schema.pm」をuseするuseする
� Schema.pmは実行するプログラムから見えるようにSchema
ファイルを生成する必要がある
Schema.pm
実行ファイルからSchema.pmが離れた位置にある場合は、
「FindBin::libs」
実行ファイル
を使って読ませる。
このやり方は、自作モジュールを一括管理するとき便利。
ORマッピングする前use TrushCliper::DB;
(中略)
my ($sql, @bind);
my $db = TrushCliper::DB->new();
$db->DBConnect();
$sql = “INSERT INTO tclipers (title, url, comment, date) ”;
$sql.= “VALUES (?,?,?,?)”;$sql.= “VALUES (?,?,?,?)”;
@bind = ($title, $url, $comment, $date);
$db->register($sql, @bind);
$db->Close();
ORマッピングした後use MyLibs::Common::DB::Config;use MyLibs::Common::DB::Schema;
(中略)
my $connect_info = ["dbi:$db_conf->{dbms}:dbname=$dbname;host=$db_conf->{host}",$db_conf->{user}, $db_conf->{pass}];
my $schema = MyLibs::Common::DB::Schema->connect(@{$connect_info});$schema->storage->dbh->do("SET names utf8");
データベース接続
my $result = $schema->resultset($schema_name)->find_or_new({title => $title,url => $url,url_hash => $url_hash,comment => $comment,date => $date
});
unless ($result->in_storage) {$result->insert;
}
Insert文と同様
ORマッピングしてみて
� コードはきれいになる
� 単純なSQLですむときはORMでいいと思った
� 学習コストがかかる。ORマッパーごとに� 学習コストがかかる。ORマッパーごとに微妙に使い方が違う。
� 結局工数は大して変わらない気がする
� コードをきれいにするだけならストアドプロシージャでもいい気はする
結論
時と場所を選べ!
� 時:単純なSQLな時は使える。複雑な時は使えない。い。
� 場所:大学なら使い放題。会社はPJ次第…。
技術の理解やリファクタリングなどの目的
では使えるので皆さん使ってみてはどうでしょう?