如何在不先选择记录的情况下在 Class::DBI 中进行更新?
要使用 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) 等,$object->update;
To do an insert with Class::DBI, you can simply do:
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.
Is there a better way to do this with Class::DBI? I don't want to do 42 $object->a(1), $object->b(2), etc., $object->update;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
据我所知, Class::DBI 没有一个好的方法来做到这一点,正如您所注意到的,它的
update()
方法应该在之前已经被调用的对象上调用从数据库加载。然而,您也许能够说服 Class::DBI 做您想做的事情,但是,可以使用以下方法:
如果此功能对您很重要并且您还没有深入了解您的项目,那么您肯定会拥有更好的运气较新的 Perl ORM,例如 Rose::DB::Object 或 < a href="http://www.perlfoundation.org/perl5/index.cgi?dbix_class" rel="nofollow noreferrer">DBIx::Class。 DBIx::Class 甚至包括 a Class::DBI 兼容性层。
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.You may be able to convince Class::DBI to do what you want, however, with something like this:
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. DBIx::Class even includes a Class::DBI compatibility layer.
我发现执行此操作的一种方法是覆盖对象的默认迭代器类。 这允许您拥有单个对象的集合,并在集合上使用更新方法。 Class::DBI 为此提供了一个方法:
这允许您在迭代器类中创建一个更新方法,该方法可以保存集合中的所有对象。 因此,您的代码可能看起来像这样:
这使得一些非常好的自我记录代码。 如果您走这条路,我还建议在 update() 发生时使用
is_changed
方法。 它将通过不更新未更改的行来帮助您节省时间。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:
This allows you to then make an
update
method in the iterator class that can save all of the objects in the collection. As such your code may look something like this: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. It will help you save time by not updating unchanged rows.