Class::DBI

最近Perl.com上的几篇文章(包括Phasebook设计模式)都讨论了Perl代码和数据库打交道的问题。Terrence Brannon的DBIx::Recordset一文试图展示数据库相关的程序也可以更加简单和易于维护。这篇文章是要用Class::DBI来使得这个努力更进一步。

Class::DBI奖励懒惰和简单。目标是使简单的数据库操作几乎不用编程,同时使困难的变得有可能。对很多简单的数据库应用来说,它使我们完全不用编写SQL,另一方面它也不强迫你用很复杂的数据结构来表示一个复杂查询。如果你确实需要原始SQL的功能或表达能力,它也会适时的给你让路。

最容易了解Class::DBI的方法就是用它来建立一个例子程序。这篇文章里面我要做个工具来分析我的电话帐单。

Data::BT::PhoneBill(可在CPAN下载)给我们一个从BT的网站下载电话帐单的方法。有了这个模块和一些最近的通话帐单条目,我们就可以用数据库来存储详细信息以备分析。

Class::DBI的基本概念是数据库中的每个表都有相应的类。尽管每个类都可以自己做连接(数据库)相关的事情,最好还是有个类来把这些事情封装起来。所以我们要建立数据库并为应用程序建立基类:

package My::PhoneBill::DBI;
use base 'Class::DBI';

__PACKAGE__->set_db('Main', 'dbi:mysql:phonebill', 'u/n', 'p/w');

1;

我们只是从Class::DBI继承并用'set_db'方法来建立数据库连接。目前这就是我们在这个类里面需要做的事情,下面我们开始建立用于存储通话信息的表:
CREATE TABLE call (
  callid   MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
  number   VARCHAR(20) NOT NULL,
  destination VARCHAR(255) NOT NULL,
  calldate  DATE NOT NULL,
  calltime  TIME NOT NULL,
  type    VARCHAR(50) NOT NULL,
  duration  SMALLINT UNSIGNED NOT NULL,
  cost    FLOAT(8,1)
);

为这个我们要建立相应的类:

package My::PhoneBill::Call;
use base 'My::PhoneBill::DBI';

__PACKAGE__->table('call');
__PACKAGE__->columns(All  => qw/callid number destination calldate calltime type duration cost/);

1;

我们从基类来继承连接信息,并声明我们要用的表和它包含的列。现在我们要开始填充表里面的数据了。
我们建立了一个简单的名为"populate_phone_bill"的脚本:

#!/usr/bin/Perl

use Data::BT::PhoneBill;
use My::PhoneBill::Call;

my $file = shift or die "Need a phone bill file";
my $bill = Data::BT::PhoneBill->new($file) or die "Can't parse bill";

while (my $call = $bill->next_call) {
  My::PhoneBill::Call->create({
   number   => $call->number,
   calldate  => $call->date,
   calltime  => $call->time,
   destination => $call->destination,
   duration  => $call->duration,
   type    => $call->type,
   cost    => $call->cost,
  });
}

create()调用执行SQL来为每行数据INSERT行。因为我们在使用Class::DBI而且设置了主键为AUTO_INCREMENT,我们就不需要为那个列来提供一个值。对于支持序列的数据库来说,我们也可以提醒Class::DBI需要使用哪个序列来为主键提供下一个唯一值。
现在我们已经有了一个填充了通话数据的表,接着要开始查询数据了。下面就要写个简单的脚本来报告与特定号码的通话记录。

#!/usr/bin/Perl
 
use My::PhoneBill::Call;
 
my $number = shift or die "Usage: $0 ";
 
my @calls = My::PhoneBill::Call->search(number => $number);
my $total_cost = 0;
 
foreach my $call (@calls) {
  $total_cost += $call->cost;
  printf "%s %s - %d secs, %.1f pence\n",

  $call->calldate, $call->calltime, $call->duration, $call->cost;
}
printf "Total: %d calls, %d pence\n", scalar @calls, $total_cost;

这里看到Class::DBI提供了一个'search'方法给我们用。我们提供一对对的列/值的杂凑来得到所有符合条件的记录。每个记录都是Call对象的一个实例,每个实例也有对应于列名字的存取方法。(这是一个可以调整值的方法,我们可以用来修改记录,但目前我们只关心报表)
有了这个脚本后,如果我们想看看打了报时台几次,就可以运行这个命令

>Perl calls_to 123
2002-09-17 11:06:00 - 5 secs, 8.5 pence
2002-10-19 21:20:00 - 8 secs, 8.5 pence
Total: 2 calls, 17 pence

同样的,若我们想看看某天的所有通话,就可以写个'calls_on'脚本:
#!/usr/bin/Perl
 
use My::PhoneBill::Call;
 
my $date = shift or die "Usage: $0 ";
 
my @calls = My::PhoneBill::Call->search(calldate => $date);
my $total_cost = 0;
 
foreach my $call (@calls) {
  $total_cost += $call->cost;

共4页 首页 上一页 [1] [2] [3] [4下一页 尾页>
相关信息
相关评论
相关文章
字母检索 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z