17 March 2006
This post may be outdated due to it was written on 2006. The links may be broken. The code may be not working anymore. Leave comments if needed.
* 为什么要选 DBIx::Class 而不是 Class::DBI ?
因为似乎 Class::DBI 只支持单个数据源的抽象层。而 DBIx::Class 是可以支持多个数据源。

* 为什么是 DBIx::Class::Schema ?
因为 DBIx::Class::Schema 可以先将数据库里的表抽象化而不管这个数据源是什么。你可以随便将不同的表抽象化,只要在后来的代码中指定数据源就可以。而对于不同的数据源可以构造不同的实例。

ok, 我得承认我说得可能很难理解。但是我们可以写一些代码加深我们的印象:
package Foorum::DBIC;

use strict;
use warnings;

use base qw/DBIx::Class::Schema/;

__PACKAGE__->load_classes(qw/User/);

package Foorum::DBIC::User;
use base qw/DBIx::Class/;

__PACKAGE__->load_components(qw/Core/);
__PACKAGE__->table('user');
__PACKAGE__->add_columns(qw/username password/);

上面这两段中我们没有指定这个数据库在哪个地方,而是假设有个数据库,里面会有个 user 表,表里有字段 username, password.
这种不指定数据源而是指定里面的模型结构的做法叫做 Schema, 这与以前的 Class::DBI 不同,Class::DBI 最基类中就要指定数据源。
做完了这个模型,我们就可以在实际代码中指定数据源而且使用了。
use Foorum::DBIC;

my $schema = Foorum::DBIC->connect(
'dbi:mysql:foorum1',
'root',
'pass',
{ AutoCommit => 1 },
);

my $result = $schema->resultset('User')->search( {username => 'fayland'} )->first;
print $result->password();

然后你可以在另外的数据源里使用这个 schema, 比如在上面接下来写:
my $schema2 = Foorum::DBIC->connect(
'dbi:mysql:foorum2',
'root',
'pass',
{ AutoCommit => 1 },
);

my $result2 = $schema->resultset('User')->search( {username => 'fayland'} )->first;
print $result2->password();

只要这个数据源 foorum2 里有个表是 user, 里面有字段 username, password 就可以。

这就是数据库抽象层的另一种做法,一种与 Class::DBI 不同的做法。
当然,我理解的可能有误,我得继续试下去,因为工作中是多个数据源的。非要用 DBIx::Class::Schema 不可。还得用到 Catalyst::Model::DBIC::Schema

* 参考
** perldoc DBIx::Class::Schema
** perldoc Catalyst::Model::DBIC::Schema


blog comments powered by Disqus