NHibernate中的批量更新

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NHibernate中的批量更新相关的知识,希望对你有一定的参考价值。

NHibernate中是否存在批量更新命令?据我所知,它没有。那么处理这种情况的最佳方法是什么?我想做以下事情:

  1. 从数据库中获取对象列表(让我们称之为用户列表,List<User>
  2. 更改这些对象的属性,(Users.Foreach(User=>User.Country="Antartica"
  3. 单独更新每个项目(Users.Foreach(User=>NHibernate.Session.Update(User))。
  4. 调用Session.Flush来更新数据库。

这是一个好方法吗?这会导致我的代码和数据库之间的往返很多次吗?

你怎么看?还是有更优雅的解决方案?

答案

启动NHibernate 3.2批处理作业有一些改进,可以最大限度地减少数据库往返。更多信息可以在HunabKu blog找到。这是一个例子 - 这些批量更新只进行了6次往返:

using (ISession s = OpenSession())
using (s.BeginTransaction())
{
    for (int i = 0; i < 12; i++)
    {
        var user = new User {UserName = "user-" + i};
        var group = new Group {Name = "group-" + i};
        s.Save(user);
        s.Save(group);
        user.AddMembership(group);
    }
    s.Transaction.Commit();
}
另一答案

我知道我已经迟到了,但是你想知道现在可以在NHibernate 2.1+中使用HQL

session.CreateQuery(@"update Users set Country = 'Antarctica'")
.ExecuteUpdate();
另一答案

您可以在nhibernate配置文件中设置更新的批处理大小。

<property name="hibernate.adonet.batch_size">16</property>

而且你不需要在那里调用Session.Update(User) - 只需刷新或提交一个事务,NHibernate就会为你处理事情。

编辑:我打算发布链接到nhibernate文档的相关部分,但该网站已关闭 - here's an old post from Ayende关于这个问题:

至于在这里使用NHibernate(或任何ORM)是否是一种好方法,它取决于上下文。如果你用一个值对一个大表中的每一行进行一次性更新(比如将所有用户设置为国家'Antarctica'(这是一个大陆,顺便说一下不是一个国家!),那么你应该使用sql UPDATE语句。如果您要在应用程序的一般用法中将国家/地区作为业务逻辑的一部分一次更新多个记录,那么使用ORM可能是一种更明智的方法。这取决于数量每次更新的行数。

如果您不确定,这里最明智的选择可能是在NHibernate中调整batch_size选项,看看它是如何工作的。如果系统的性能不可接受,那么您可能会在代码中实现直接的sql UPDATE语句。

另一答案

从NHibernate 5.0开始,可以使用LINQ进行批量操作。

session.Query<Cat>()
.Where(c => c.BodyWeight > 20)
.Update(c => new { BodyWeight = c.BodyWeight / 2 });

NHibernate将生成单个“更新”sql查询。

Updating entities

另一答案

您不需要更新,也不需要刷新:

IList<User> users = session.CreateQuery (...).List<User>;
users.Foreach(u=>u.Country="Antartica")
session.Transaction.Commit();

我认为NHibernate会为所有更改编写批处理。

问题是,您的用户需要加载到内存中。如果遇到问题,您仍然可以使用NHibernate使用本机SQL。但是直到你没有证明它是一个性能问题,坚持使用漂亮的解决方案。

另一答案

不,这不是一个好方法!

对于这种更新,本机SQL要好很多倍。

UPDATE USERS SET COUNTRY = 'Antartica';

简而言之,数据库引擎将比一次Java代码更有效地处理这一百倍。

以上是关于NHibernate中的批量更新的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate 中的自动更新包

如何更新 Nhibernate 中的 varchar 列长度?

如何绕过 NHibernate 版本控制更新 SQL 中的记录

踩坑了!踩坑了!NHibernate使用批量插入Oracle数据,Batch属性

NHibernate 似乎没有批量插入 PostgreSQL

Mybaits的批量操作包括批量删除 批量增加和批量更新