【问题标题】:How can I do an update in Class::DBI without selecting a record first?如何在不先选择记录的情况下在 Class::DBI 中进行更新?
【发布时间】:2009-02-04 05:09:47
【问题描述】:

要使用 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;

这效率不高,因为我必须先执行 SELECT,然后执行 UPDATE 而不是仅执行一次 UPDATE。

有没有更好的方法来使用 Class::DBI?我不想做 42 $object->a(1), $object->b(2), etc., $object->update;

【问题讨论】:

  • DBIx::Class 让这一切变得简单。你真的应该考虑离开 CDBI。

标签: perl class-dbi


【解决方案1】:

据我所知,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 等较新的 Perl ORM 之一肯定会更好。 DBIx::Class 甚至包括a Class::DBI compatibility layer

【讨论】:

    【解决方案2】:

    我发现这样做的一种方法是覆盖对象的默认迭代器类。这使您可以使用集合上的更新方法来拥有单个对象的集合。 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();
    

    这使得一些非常好的自我记录的代码。如果你走这条路,我还建议在 update() 发生时使用is_changed 方法。它将通过不更新未更改的行来帮助您节省时间。

    【讨论】:

      猜你喜欢
      • 2010-09-17
      • 2019-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-12
      • 2019-06-04
      相关资源
      最近更新 更多