2013-11-03 74 views
0

在我的腳本創建是使用包裝DBI的幾個不同的對象:的Perl DBI一個來自不同對象的連接:問題

package MY::DB; 
use DBI; 

sub my_connect { 
    my ($class, %p) = @_; 
    my $dbh = DBI->connect(...); 
    $dbh->do("SET NAMES cp1251"); 
    return bless {dbh => $dbh}, $class; 
} 

sub query { 
    my ($self, $sql) = @_; 
    # sql execution 
} 
... 

我決定只使用一個連接到數據庫來優化腳本。嘗試了兩個選項:全局變量和DBI-> connect_cached(..)的方法。其結果是一樣的:連接實際上是用一個所有對象,但連接之後,不處理的SQL代碼:

... 
sub my_connect { 
    my ($class, %p) = @_; 
    my $dbh = DBI->connect_cached(...); 
    $dbh->do("SET NAMES cp1251"); # no effect :(
    return bless {dbh => $dbh}, $class; 
} 
... 

比如我有類:

package MY::USER; 
use base 'MY::DB'; 
sub constructor { 
    my ($class) = @_; 
    return MY::DB::my_connect($class); 
} 
sub get_info_1 { 
    my ($self) = @_; 
    $self->query(...); 
} 
sub get_info_2 { 
    my ($self) = @_; 
    $self->query(); 
} 

package MY::NEWS; 
use base 'MY::DB'; 
sub constructor { 
    my ($class) = @_; 
    return MY::DB::my_connect($class); 
} 
sub get_info { 
    my ($self) = @_; 
    $self->query(...); 
} 

腳本:

use MY::USER; 
use MY::NEWS; 

my $user = MY::USER->constructor; 
my $news = MY::NEWS->constructor; 

$user->get_info_1; # OK 
$news->get_info; # OK 
$user->get_info_2; # here $dbh->do("set names cp1251") operation no effect 
+0

是的,但它是DBI的包裝(agregation),而不是子類... – user2950248

+0

如果我使用connect_cached(),那麼do(「set names ...」)不起作用(不適用於所有對象) – user2950248

+1

什麼數據庫?要複製的最小代碼? – ikegami

回答

0

我找到了我的問題的答案!

主要DBI類有析構函數:

sub DESTROY { 
    my ($self) = @_; 
    $self->{dbh}->disconnect; 
} 

而且該類的所有孩子的擁有它。 Inside NEWS-> get_info()調用並銷燬相同的對象,並鏈接到數據庫斷開連接...但DBH變量的值已定義!