2013-07-26 55 views
2

SO。Perl:如何避免全局数据库并保持数据库连接

也许标题显得过于宽泛,我在具体问题。

我有一个连接到SQLite数据库Perl脚本。在运行期间,我执行了很多数据库操作,例如SELECT,INSERT,UPDATE等。我将每个数据库操作都包装在其自己的子例程中(主要是为了隐藏SQL语句以及对结果集的任何额外处理)。

我要使用同一个数据库处理程序对象每次我需要调用这个数据库操作子程序的一次,所以我一直在做的是通过数据库处理程序对象作为参数。例如:

my $dbh = DBI->connect("dbi:SQLite:dbname=db.db", "", "") or die; 

sub select_from_systems { 
    my $dbh = shift; 
    return $dbh->selectcol_arrayref("SELECT hostname FROM systems"); 
} 

正如旁注,我使用Perl DBI。

我只是想知道是否有一个更聪明的方式来做到这一点,所以我不必须通过数据库处理程序对象作为参数。

我想避免全局变量,我不觉得他们是瘟疫,在这种情况下,它可能是合理的,但仍。

任何帮助或洞察力非常感谢。

问候。

回答

2

如果你真的想你的数据库的处理程序是一个Singleton(例如每Perl的过程中的一个),您可以:

  • 使用our范围的别名全局变量。这不像面向对象的方法那么整洁,但它通常很好地工作,没有缺点 - 推荐使用our的极少数情况之一。

  • 将其设置为our,但为其创建类级别(例如非对象)setter和getter方法。

  • 将它作为一个真正的单身。这里讨论的技术是:How can I implement a singleton class in perl?

+0

感谢一些选项。鉴于我的代码的状态和截止日期,我将与您的第二个解决方案,我们的范围别名一起去。它只是适合becasue我发现相当麻烦是通过这样的说法,每一次,我已经知道这是什么我只需要它在子程序的范围。非常感谢您的时间! – romeroqj

4

使你的模块面向对象。这仍然会通过句柄作为参数,但语法更好。

package MyConnection; 

sub new { 
    my $class = shift; 
    my $dbh = DBI->new(@_); 
    bless \$dbh, $class; 
} 

sub select_from_systems { 
    my $self = shift; 
    $$self->selectcol_arrayref(...); 
} 

然后:

my $db = MyConnection->new(@credentials); 
...; 
my $result = $db->select_from_systems; 

为了模拟对象,我在这里用一个简单的标量的参考,但您可能希望传统的基于散列的OO(或者只是使用麋)。

3

这听起来像是一个应该考虑使用面向对象Perl的情况。如果您不熟悉面向对象的编程,其中一个好处是您可以拥有一组函数,这些函数都可以对一些常用数据(在本例中为数据库引用)进行操作。

一个不错的低层次的介绍OO Perl是perlootut on Perldoc,虽然看起来流行使用的模块,如驼鹿,当你在Perl做大规模的面向对象编程。

现在,在幕后,Perl的仍然绕过对象(某种参考,通常是哈希REF),并与基本OO Perl中,函数本身仍然需要明确地处理这个问题。然而,它使调用语义更好,如下列:

my $database_object = new DatabaseObject("dbi:SQLite:dbname=db.db"); 
$database_object->select_from_systems(); 

相应函数的定义是这样的:

package DatabaseObject; 
sub new { 
    my $class = shift; 
    my $dbpath = shift; 
    my $dbh = DBI->connect($dbpath, "", "") or die; 

    my $self = {_dbh => $dbh}; 
    bless $self, $class; 
    return $self; 
} 

sub select_from_systems { 
    my $self = shift; 
    return $self->{_dbh}->selectcol_arrayref("SELECT hostname FROM systems"); 
}