bulkupdate
Hibernate3.0 采用新的基于ANTLR的HQL/sql查询翻译器,在Hibernate的配置文件中,hibernate.query.factory_class属性用来选择查询翻译器。
(1)选择Hibernate3.0的查询翻译器:
hibernate.query.factory_class= org.hibernate.hql.ast.ASTQueryTranslatorFactory
(2)选择Hibernate2.1的查询翻译器
hibernate.query.factory_class= org.hibernate.hql.classic.ClassicQueryTranslatorFactory
为了使用3.0的批量更新和删除功能,只能选择(1)否则不能解释批量更新的语句。选择(2)但没法解释批量更新语句了。
大批量更新/删除(Bulk update/delete)
就像已经讨论的那样,自动和透明的 对象/关系 映射(object/relational mAPPing)关注于管理对象的状态。 这就意味着对象的状态存在于内存,因此直接更新或者删除 (使用 sql 语句 UPDATE 和 DELETE) 数据库中的数据将不会影响内存中的对象状态和对象数据。 不过,Hibernate提供通过Hibernate查询语言来执行大批 量SQL风格的(UPDATE)和(DELETE) 语句的方法。
UPDATE 和 DELETE语句的语法为: ( UPDATE | DELETE ) FROM? ClassName (WHERE WHERE_CONDITIONS)?。 有几点说明:
在FROM子句(from-clause)中,FROM关键字是可选的
在FROM子句(from-clause)中只能有一个类名,并且它不能有别名
不能在大批量HQL语句中使用连接(显式或者隐式的都不行)。不过在WHERE子句中可以使用子查询。
整个WHERE子句是可选的。
举个例子,使用Query.executeUpdate()方法执行一个HQL UPDATE语句:
session session = sessionfactory.openSession();
transaction tx = session.beginTransaction();
String hqlUpdate = "update Customer set name = :newName where name = :oldName";
int updatedEntities = s.createQuery( hqlUpdate ) .setString( "newName", newName ) .setString( "oldName", oldName ) .executeUpdate(); tx.commit();
session.close();
执行一个HQL DELETE,同样使用 Query.executeUpdate() 方法 (此方法是为 那些熟悉JDBC Preparedstatement.executeUpdate() 的人们而设定的)
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlDelete = "delete Customer where name = :oldName";
int deletedEntities = s.createQuery( hqlDelete ) .setString( "oldName", oldName ) .executeUpdate();
tx.commit();
session.close();
由Query.executeUpdate()方法返回的整型值表明了受此操作影响的记录数量。 注意这个数值可能与数据库中被(最后一条SQL语句)影响了的“行”数有关,也可能没有。一个大批量HQL操作可能导致多条实际的SQL语句被执行, 举个例子,对joined-subclass映射方式的类进行的此类操作。这个返回值代表了实际被语句影响了的记录数量。在那个joined-subclass的例子中, 对一个子类的删除实际上可能不仅仅会删除子类映射到的表而且会影响“根”表,还有可能影响与之有继承关系的joined-subclass映射方式的子类的表。
------------------------------------------------------------------------------------------------
我在 Spring + hibernate 中 使用
String sql = "delete PlanPackageRelations where ppfId = "+ppfId;
int a = this.getHibernateTemplate().getSessionFactory().openSession().createQuery(sql).executeUpdate();
结果控制台输出一下信息:
在本地事务包含边界中使用的资源 jdbc/cnas 的可分享连接 MCwrapper id 19911991 Managed connection com.ibm.ws.rsadapter.spi.WSRdbManagedConnectionImpl@12781278 State:STATE_TRAN_WRAPPER_INUSE
-------------------------------------------------------------------------------------------------
调用jdbc 处理根据非主键删除。
/**
* 根据ppfId ,删除PlanPackageRelations。
* @param ppfId
*/
public void deletePlanPackageRelations(String ppfId){
final String ppfIdFinal = ppfId;
try {
this.getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session) throws HibernateException, SQLException {
List result = new ArrayList();
String sql = "delete PlanPackageRelations where ppfId = :ppfId";
Query query = session.createQuery(sql).setString("ppfId",ppfIdFinal);
result.add(new integer(query.executeUpdate()));
return result;
}
});
// String sql = "delete PlanPackageRelations where ppfId = "+ppfId;
// int a = this.getHibernateTemplate().getSessionFactory().openSession().createQuery(sql).executeUpdate();
//
}catch(DataAccessException t){
t.printstacktrace();
throw t;
}catch (Exception e) {
e.printStackTrace();
}
}
--------------------------------------------------------------------------------------------
使用HibernateTemplate批量删除数据
使用spring + hibernate框架中,一般使用hibernateTemplate来使用Hibernate,但hibernateTemplate
的 bulkupdate()不能实现动态的批量删除,即使用bulkUplate时要事先确定下占位符”?“的个数,然后再使用其重载方法 bulkUpdate(queryString, Object[]),此时,Object[]内的元素个数就要跟queryString中的占位符“?”的个数相等,使用十分麻烦,因此可以使用 HibernateCallback回调函数来进行动态批量删除,即可以不考虑要删除元素的个数。具体使用方法如下例:
public void bulkDelete(final Object[] ids) throws Exception {
final String queryString = "delete persistentModel where id in (:ids) ";
super.execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Query query = session.createQuery(queryString);
query.setparameterList("ids", ids);
return query.executeUpdate();
}
});
}
注:标红处的占位符要加上(),否则会抛出语法错误异常。
-----------------------------------------------------------------------------------------
bulkUpdate 使用:
String updateSql = "update Rsceref ref set ref.rulecode = ? where ref.rscerefcode = ?";
getHibernateTemplate().bulkUpdate(updateSql, new Object[]{chkObj.getBmcrcode(),listExistRuleSql.get(0)});
this.getHibernateTemplate().bulkUpdate(sql);