2009-02-04 27 views
6

Để làm một chèn với Class :: DBI, bạn chỉ có thể làm:Tôi làm cách nào để cập nhật trong Class :: DBI mà không chọn bản ghi đầu tiên?

my $object = Object::DB->insert({ a => 1, b => 2, c => 3, ...}); 

Nhưng không có điều như vậy để cập nhật. Điều tốt nhất tôi có thể đưa ra được lựa chọn kỷ lục đầu tiên sau đó cập nhật nó:

my $object = Object::DB->retrieve($id); 
my $object->set(a => 1, b => 2, c => 3, ...}; 
$object->update; 

Đây không phải là hiệu quả kể từ khi tôi phải làm một SELECT đầu tiên, và sau đó một UPDATE thay vì chỉ một UPDATE.

Có cách nào tốt hơn để thực hiện việc này với Class :: DBI không? Tôi không muốn làm 42 $ object-> a (1), $ object-> b (2), vv, $ object-> update;

+0

DBIx :: Lớp giúp việc này trở nên dễ dàng. Bạn thực sự nên xem xét di chuyển ra khỏi CDBI. – jrockway

Trả lời

6

Theo như tôi biết, Class :: DBI không có cách nào tốt để làm điều này, Như bạn đã lưu ý, phương thức update() của nó có nghĩa là được gọi trên một đối tượng đã được tải trước đó từ cơ sở dữ liệu.

Bạn có thể để thuyết phục Class :: DBI để làm những gì bạn muốn, tuy nhiên, với một cái gì đó như thế này:

# Make new "empty" object 
my $o = My::CDBI::Object->new; 

# Set the primary key column and discard the change 
$o->set(your_pk_column => 123); 
$o->discard_changes; 

# Set your other columns 
$o->set(a => 'foo', b => 'bar'); 

# Do the update 
$o->update; 

Nếu tính năng này là quan trọng với bạn và bạn chưa phải quá xa vào dự án của bạn, bạn chắc chắn sẽ có may mắn hơn với một trong các ORM Perl mới hơn như Rose::DB::Object hoặc DBIx::Class. DBIx :: Lớp thậm chí bao gồm a Class::DBI compatibility layer.

4

Một cách mà tôi đã tìm thấy để thực hiện việc này là ghi đè lớp trình lặp mặc định cho các đối tượng của bạn. Điều này cho phép bạn có một bộ sưu tập các đối tượng riêng lẻ với một phương thức cập nhật trên bộ sưu tập. Lớp :: DBI cung cấp một phương pháp cho việc này:

__PACKAGE__->iterator_class('MyClass::CDBI::Iterator'); 

này cho phép bạn để sau đó thực hiện một phương pháp update trong lớp iterator có thể lưu tất cả các đối tượng trong bộ sưu tập. Vì vậy, mã của bạn có thể trông giống như sau:

my $collection = Object::DB->search_where({id => {'>=', 0}}); 
foreach my $obj ($collection->next()) { 
    $obj->a('bob'); 
    $obj->b('tom'); 
} 
$collection->update(); 

Điều này làm cho một số mã tự viết khá tốt. Nếu bạn đi tuyến đường này, tôi cũng khuyên bạn nên đặt phương thức is_changed vào sử dụng khi cập nhật() xảy ra. Nó sẽ giúp bạn tiết kiệm thời gian bằng cách không cập nhật các hàng không thay đổi.

Các vấn đề liên quan