在完全的对象/关系映射中,批量处理通常很难。ORM 都是关于对象状态管理的,这意味着对象状态在内存中可用。然而,Hibernate 有些用于优化批量处理的功能,这些功能在 Hibernate 参考指南中进行介绍,然而,EJB3 持续性略有不同。
如已讨论的那样,自动而透明的对象/关系映射与对象状态管理有关。这意味着对象状态在内存中可用,因此直接在数据库中更新或删除(使用 SQL UPDATE
和 DELETE
)数据不会影响内存中的状态。但是,Hibernate 提供了通过 JP-QL 执行批量 SQL 风格 UPDATE
和 DELETE
语句的方法(第 8 章,JP-QL:对象查询语言)。
UPDATE
和 DELETE
语句的伪语法为:( UPDATE | DELETE ) FROM? ClassName (WHERE WHERE_CONDITIONS)?
。请注意
在 from 子句中,FROM 关键字是可选的。
在 from 子句中只能指定一个类名,并且不能有别名(这是 Hibernate 当前的限制,并将很快消除)。
在批量 JP-QL 查询中不能指定任何连接(隐式或显式)。可以在 where 子句中使用子查询。
where 子句也是可选的。
例如,要执行 JP-QL UPDATE
,请使用 Query.executeUpdate()
方法
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
String jpqlUpdate = "update Customer set name = :newName where name = :oldName"
int updatedEntities = entityManager.createQuery( jpqlUpdate )
.setParameter( "newName", newName )
.setParameter( "oldName", oldName )
.executeUpdate();
entityManager.getTransaction().commit();
entityManager.close();
要执行 JP-QL DELETE
,请使用相同的 Query.executeUpdate()
方法(该方法的名称面向那些熟悉 JDBC 的 PreparedStatement.executeUpdate()
的人)
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
String hqlDelete = "delete Customer where name = :oldName";
int deletedEntities = entityManager.createQuery( hqlDelete )
.setParameter( "oldName", oldName )
.executeUpdate();
entityManager.getTransaction().commit();
entityManager.close();
由 Query.executeUpdate()
方法返回的 int
值指示受操作影响的实体数。这可能与数据库中受影响的行数相关,也可能不相关。例如,对于联接子类,JP-QL 批量操作可能导致执行多个实际 SQL 语句。返回的数字指示受该语句影响的实际实体数。回到联接子类的示例中,针对一个子类的删除实际可能导致不仅删除映射到该子类的表,还删除“根”表和继承层次结构中更下方的联接子类表。
版权 © 2005 Red Hat Inc. 及各作者