简体   繁体   English

如何在不首先选择记录的情况下在Class :: DBI中进行更新?

[英]How can I do an update in Class::DBI without selecting a record first?

To do an insert with Class::DBI, you can simply do: 要使用Class :: DBI进行插入,您只需执行以下操作:

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

But there is no such thing for update. 但是没有更新的东西。 The best I could come up with is selecting the record first then updating it: 我能想到的最好的是先选择记录然后更新它:

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

This is not efficient since I have to do a SELECT first, and then an UPDATE instead of just one UPDATE. 这是没有效率的,因为我必须首先执行SELECT,然后执行UPDATE而不是仅执行一次UPDATE。

Is there a better way to do this with Class::DBI? 使用Class :: DBI有更好的方法吗? I don't want to do 42 $object->a(1), $object->b(2), etc., $object->update; 我不想做42 $ object-> a(1),$ object-> b(2)等,$ object-> update;

As far as I know, Class::DBI does not have a good way to do this, As you've noted, its update() method is meant to be called on an object that has been previously loaded from the database. 据我所知,Class :: DBI没有很好的方法来实现这一点,正如你所指出的,它的update()方法是在一个先前从数据库加载的对象上调用的。

You may be able to convince Class::DBI to do what you want, however, with something like this: 你或许可以说服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;

If this feature is important to you and you're not already too far into your project, you will definitely have better luck with one of the newer Perl ORMs such as Rose::DB::Object or DBIx::Class . 如果这个功能对你很重要而且你的项目已经不是很远了,你肯定会有更好的运气,比如Rose :: DB :: ObjectDBIx :: Class等新的Perl ORM。 DBIx::Class even includes a Class::DBI compatibility layer . DBIx :: Class甚至包括Class :: DBI兼容层

One way that I've found to do this is to override the default iterator class for your objects. 我发现这样做的一种方法是覆盖对象的默认迭代器类。 This allows you to have a collection of individual objects with an update method on the collection. 这允许您使用集合上的更新方法获得单个对象的集合。 Class::DBI provides an method for this: Class :: DBI为此提供了一种方法:

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

This allows you to then make an update method in the iterator class that can save all of the objects in the collection. 这允许您在迭代器类中创建一个可以保存集合中所有对象的update方法。 As such your code may look something like this: 因此,您的代码可能如下所示:

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

Which makes for some pretty well self-documented code. 这使得一些非常好的自编代码。 If you go this route, I'd also suggest putting the is_changed method into use as the update() occurs. 如果你走这条路线,我还建议在发生update()时使用is_changed方法。 It will help you save time by not updating unchanged rows. 它将通过不更新未更改的行来帮助您节省时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM