程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> hibernate批量操作實例詳解

hibernate批量操作實例詳解

編輯:關於JAVA

hibernate批量操作實例詳解。本站提示廣大學習愛好者:(hibernate批量操作實例詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是hibernate批量操作實例詳解正文


本文實例講述了hibernate批量操作的辦法。分享給年夜家供年夜家參考,詳細以下:

Hibernate的批量處置

Hibernate完整以面向對象的方法來操作數據庫,當法式裡以面向對象的方法操作耐久化對象時,將被主動轉換為對數據庫的操作。例如挪用Session的delete()辦法來刪除耐久化對象,Hibernate將擔任刪除對應的數據記載;當履行耐久化對象的set辦法時,Hibernate將主動轉換為對應的update辦法,修正數據庫的對應記載。

成績是假如須要同時更新100 000筆記錄,是否是要一一加載100 000筆記錄,然後順次挪用set辦法——如許不只繁瑣,數據拜訪的機能也非常蹩腳。對這類批量處置的場景,Hibernate供給了批量處置的處理計劃,上面分離從批量拔出、批量更新和批量刪除3個方面引見若何面臨這類批量處置的情況。

1  批量拔出

假如須要將100 000筆記錄拔出數據庫,平日Hibernate能夠會采取以下做法:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
 User u = new User (.....);
 session.save(customer);
}
tx.commit();
session.close();

但跟著這個法式的運轉,總會在某個時刻運轉掉敗,而且拋出OutOfMemoryException(內存溢出異常)。這是由於Hibernate的Session持有一個必選的一級緩存,一切的User實例都將在Session級其余緩存區停止了緩存的原因。

為懂得決這個成績,有個異常簡略的思緒:准時將Session緩存的數據刷新入數據庫,而不是一向在Session級別緩存。可以斟酌設計一個累加器,每保留一個User實例,累加器增長1。依據累加器的值決議能否須要將Session緩存中的數據刷入數據庫。

上面是增長100 000個User實例的代碼片斷:

private void testUser()throws Exception
{
 //翻開Session
 Session session = HibernateUtil.currentSession();
 //開端事務
 Transaction tx = session.beginTransaction();
 //輪回100 000次,拔出100 000筆記錄
 for (int i = 0 ; i < 1000000 ; i++ )
 {
  //創立User實例
  User u1 = new User();
  u1.setName("xxxxx" + i);
  u1.setAge(i);
  u1.setNationality("china");
  //在Session級別緩存User實例
  session.save(u1);
  //每當累加器是20的倍數時,將Session中的數據刷入數據庫,並清空Session緩存
  if (i % 20 == 0)
  {
   session.flush();
   session.clear();
   tx.commit();
   tx = session.beginTransaction();
  }
 }
 //提交事務
 tx.commit();
 //封閉事務
 HibernateUtil.closeSession();
}

下面代碼中,當i%20 == 0時,手動將Session處的緩存數據寫入數據庫,並手動提交事務。假如不提交事務,數據將仍然緩存在事務處——未進入數據庫,也將惹起內存溢出的異常。

這是對Session級別緩存的處置,還應當經由過程以下設置裝備擺設來封閉SessionFactory的二級緩存。

hibernate.cache.use_second_level_cache false

留意:除要手動清空Session級其余緩存外,最好封閉SessionFactory級其余二級緩存。不然,即便手動清空Session級其余緩存,但由於在SessionFactory級別還有緩存,也能夠激發異常。

2  批量更新

下面引見的辦法異樣實用於批量更新數據,假如須要前往多行數據,可使用scroll()辦法,從而可充足應用辦事器端游標所帶來的機能優勢。上面是停止批量更新的代碼片斷:

private void testUser()throws Exception
{
 //翻開Session
 Session session = HibernateUtil.currentSession();
 //開端事務
 Transaction tx = session.beginTransaction();
 //查詢出User表中的一切記載
 ScrollableResults users = session.createQuery("from User")
  .setCacheMode(CacheMode.IGNORE)
  .scroll(ScrollMode.FORWARD_ONLY);
 int count=0;
 //遍歷User表中的全體記載
 while ( users.next() )
 {
  User u = (User) users.get(0);
  u.setName("新用戶名" + count);
  //當count為20的倍數時,將更新的成果從Session中flush到數據庫
  if ( ++count % 20 == 0 )
  {
   session.flush();
   session.clear();
  }
 }
 tx.commit();
 HibernateUtil.closeSession();
}

經由過程這類方法,固然可以履行批量更新,但後果異常欠好。履行效力不高,並且須要先履行數據查詢,然後再履行數據更新,而且這類更新將是逐行更新,即每更新一行記載,都須要履行一條update語句,機能異常低下。
為了不這類情形,Hibernate供給了一品種似於SQL的批量更新和批量刪除的HQL語法。

3  SQL作風的批量更新/刪除

Hibernate供給的HQL語句也支撐批量的UPDATE和DELETE語法。
批量UPDATE和DELETE語句的語法格局以下:

UPDATE | DELETE FROM? ClassName [WHERE WHERE_CONDITIONS]

關於下面的語法格局有以下四點值得留意:

● 在FROM子句中,FROM症結字是可選的。即完整可以不寫FROM症結字。
● 在FROM子句中只能有一個類名,該類名不克不及有別號。
● 不克不及在批量HQL語句中應用銜接,顯式的或隱式的都不可。但可以在WHERE子句中應用子查詢。
● 全部WHERE子句是可選的。

假定,須要批量更改User類實例的name屬性,可以采取以下代碼片斷完成:

private void testUser()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() 辦法,上面是一次刪除下面全體記載的代碼片斷:

private void testUser()throws Exception
{
 //翻開Session實例
 Session session = HibernateUtil.currentSession();
 //開端事務
 Transaction tx = session.beginTransaction();
 //界說批量刪除的HQL語句
 String hqlUpdate = "delete User";
 //履行批量刪除
 int updatedEntities = session.createQuery( hqlUpdate )
       .executeUpdate();
 //提交事務
 tx.commit();
 //封閉Session
 HibernateUtil.closeSession();
}

由Query.executeUpdate()辦法前往一個整型值,該值是受此操作影響的記載數目。現實上,Hibernate的底層操作是經由過程JDBC完成的。是以,假如有批量的UPDATE或DELETE操作被轉換成多條UPDATE或DELETE語句,該辦法前往的是最初一條SQL語句影響的記載行數。

願望本文所述對年夜家基於Hibernate框架的Java法式設計有所贊助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved