天天看點

hibernate批量删除和更新資料

轉載自:javascript:void(0)

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)中,FROMkeyword是可選的

在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() 的人們而設定的)

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 connectioncom.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 使用: