DML风格的批量更新/删除

转自:http://javaligang.blog.51cto.com/5026500/912874

Hibernate提供的HQL语句也支持批量的UPDATE和DELETE语法。
批量UPDATE 和 DELETE语句的语法格式如下:
UPDATE | DELETE FROM? <ClassName>  [WHERE WHERE_CONDITIONS]
关于上面的语法格式有如下4点值得注意:
Ø  在FROM子句中,FROM关键字是可选的,即完全可以不写FROM关键字。
Ø  在FROM子句中只能有一个类名,该类名不能有别名。
Ø  不能在批量HQL语句中使用连接,显式或者隐式的都不行。但可以在WHERE子句中使用子查询。
Ø  整个WHERE子句是可选的。WHERE子句的语法和HQL语句中WHERE子句的语法完全相同。
假设对于上面需要批量更改User类实例的name属性,可以采用如下代码片段完成。
程序清单:codes\06\6.3\batchUpdate2\src\lee\UserManager.java

private void updateUsers()throws Exception  
{  
    //打开Session  
    Session session = HibernateUtil.currentSession();  
    //开始事务  
    Transaction tx = session.beginTransaction();  
    //定义批量更新的HQL语句  
    String hqlUpdate = "update User set name = :newName";  
    //执行更新  
    int updatedEntities = session.createQuery( hqlUpdate )  
        .setString( "newName", "新名字" )  
        .executeUpdate();  
    //提交事务  
    tx.commit();  
    HibernateUtil.closeSession();  
}  


从上面的代码中可以看出,这种语法非常类似于PreparedStatement的executeUpdate()语法,实际上,HQL的这种批量更新就是直接借鉴了SQL语法的UPDATE语句。
注意:

使用这种批量更新语法时,通常只需要执行一次SQL的UPDATE语句,就可以完成所有满足条件记录的更新。但也可能需要执行多条UPDATE语句,这是因为有继承映射等特殊情况,例如有一个Person实例,它有Customer子类实例。当批量更新Person实例时,也需要更新Customer实例。如果采用joined-subclass或union-subclass映射策略时,Person和Customer实例保存在不同的表中,因此可能需要多条UPDATE语句。

执行一个HQL DELETE,同样使用 Query.executeUpdate() 方法,下面是一次删除上面全部记录的代码片段。
程序清单:codes\06\6.3\batchDelete\src\lee\UserManager.java

private void deleteUsers()throws Exception  
{  
    //打开Session  
    Session session = HibernateUtil.currentSession();  
    //开始事务  
    Transaction tx = session.beginTransaction();  
    //定义批量删除的HQL语句  
    String hqlDelete = "delete User";  
    //执行删除  
    int deletedEntities = session.createQuery( hqlDelete )  
        .executeUpdate();  
    //提交事务  
    tx.commit();  
    HibernateUtil.closeSession();  
}  

Query.executeUpdate()方法返回一个整型值,该值是受此操作影响的记录数量。我们知道,Hibernate的底层操作实际上是由JDBC完成的,因此,如果有批量UPDATE或DELETE操作被转换成多条UPDATE或DELETE语句,该方法将只能返回最后一条SQL语句影响的记录行数。

你可能感兴趣的:(Hibernate)