Hibernate提供的HQL語句也支持批量的UPDATE和DELETE語法。
批量UPDATE 和 DELETE語句的語法格式如下:
關於上面的語法格式有如下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語句影響的記錄行數。