5

Class::DBI で挿入するには、次のようにします:

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

しかし、更新にはそのようなものはありません。私が思いつく最善の方法は、最初にレコードを選択してから更新することです。

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

これは、1 回の UPDATE ではなく、最初に SELECT を実行し、次に UPDATE を実行する必要があるため、効率的ではありません。

Class::DBI でこれを行うより良い方法はありますか? 42 $object->a(1)、$object->b(2) など、$object->update; はやりたくありません。

4

2 に答える 2

6

私の知る限り、Class :: DBIにはこれを行うための良い方法がありません。ご存知のように、そのupdate()メソッドは、以前にデータベースからロードされたオブジェクトに対して呼び出されることを目的としています。

Class :: DBIに、次のような方法でやりたいことを実行するように説得できる場合があります。

# 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;

この機能があなたにとって重要であり、あなたがまだプロジェクトにあまり深く関わっていないのであれば、 Rose :: DB::ObjectDBIx::Classなどの新しいPerlORMの1つで間違いなく幸運があります。DBIx :: Classには、Class::DBI互換性レイヤーも含まれています。

于 2009-02-04T13:43:39.887 に答える
4

これを行うために私が見つけた1つの方法は、オブジェクトのデフォルトのイテレータクラスをオーバーライドすることです。これにより、コレクションのupdateメソッドを使用して個々のオブジェクトのコレクションを作成できます。Class :: DBIは、このためのメソッドを提供します。

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

これによりupdate、コレクション内のすべてのオブジェクトを保存できるイテレータクラスのメソッドを作成できます。そのため、コードは次のようになります。

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

これは、かなりよく自己文書化されたコードになります。is_changedこのルートを使用する場合は、update()が発生したときにメソッドを使用することもお勧めします。変更されていない行を更新しないことで時間を節約できます。

于 2009-02-04T14:33:00.380 に答える