Hibernate批處理操作優化 (批量插入、更新與刪除)


 

Hibernate的一級緩存影響。

        我們每次保存的東西都會保存在Session緩存中,這就是Hibernate的一級緩存,如果我們一直循環執行save等操作,緩存里東西會越來越多,速度也就越來越慢,服務器一直在循環處理,自然也會增加負載。

       這本來就是Hibernate不擅長的地方,而且一級緩存不可以不用,如果我們要保存的數據量十分巨大,那么在程序中執行添加、更新方法時,Session對象自身開辟的一級緩存會不斷消耗,直至OutOfMemoryError (內存溢出異常)。

解決方案

 

批量插入優化

 

    1、仍舊用Hibernate API來進行批處理,但在一定的量的時候,及時的清除緩存。

 

     1)優化Hibernate,在配置文件中設置hibernate.jdbc.batch_size參數,來指定每次提交SQL的數量。 配置hibernate.jdbc.batch_size參數的原因就是盡量少讀數據庫,hibernate.jdbc.batch_size參數值越大,讀數據庫的次數越少,速度越快。

 

<!--設置hibernate.jdbc.batch_size參數--> <hibernate-configuration> <session-factory> ......... <property name="hibernate.jdbc.batch_size">50</property> ......... <session-factory> <hibernate-configuration> 

 

   2)程序及時清除緩存,即每插入一定量的數據后及時把它們從內部緩存中清除掉,釋放占用的內存

 

     如下代碼:

 

// 每處理50條清空緩存
session.save(myObject);
if (i%50 == 0) {
    session.flush();
    session.clear();
}

// 在我的項目中寫法如下:
if (i%50 == 0) {
    this.getHibernateTemplate().flush();
    this.getHibernateTemplate().clear();
}

 

  2、通過JDBC API來做批量插入,繞過Hibernate API。這個方法性能上是最好的,也是最快的。

     由於session.connection()方法已經過時,我們可以通過下面方法獲得Connection連接,但是仍然可以使用的

  private Connection getJdbcConnection(){
       
          //1,獲取SessionFactory
          SessionFactory factory=super.getHibernateTemplate().getSessionFactory();
          //2,獲取數據源
          DataSource ds=SessionFactoryUtils.getDataSource(factory);
          try {

    //3,通過數據源獲取Jdbc連接
              return ds.getConnection();
          } catch (SQLException e) {
              logger.error("Hibernate-->Jdbc時沒有獲取到連接...", e);
          }
          return null;
      }

 

 

示例代碼:

 

String insertSql = "insert into user(name,address) values(?,?)";
Session session = getHibernateTemplate().getSessionFactory().openSession();
Connection conn = session.connection();
PrepareStatement stmt = conn.prepareStatement(insertSql);

// 方式1:自動提交
conn.setAutoCommit(true);
for(int i = 0; i++; i<10000) {
    stmt.setString(1, "testName");
    stmt.setString(2, "testAddress");
    stmt.execute();
}

// 方式2:批量提交
conn.setAutoCommit(false);
for(int i = 0; i++; i<10000) {
    stmt.setString(1, "testName");
    stmt.setString(2, "testAddress");
    stmt.addBatch();
    if (i % 100 == 0) {
        stmt.executeBatch();
        conn.commit();
    }
}
stmt.executeBatch();
conn.commit();

// 關閉session
session.close();


 

 

批量更新與刪除優化

 

Hibernate2中,對於批量更新/刪除操作,都是先將符合要求的數據查出來,然后再做更新/刪除操作。這樣一來會占用大量內存,而且海量數據處理的時候性能很低。

 

而Hibernate3對批量更新/刪除提供了支持,能夠直接執行批量更新或批量刪除語句,無需把被更新或刪除的對象先加載到內存中,類似於JDBC的批量更新/刪除操作。

 

不過對於循環處理數據更新和刪除場景,建議還是使用JDBC,方法同上:批量插入的方法2。

 

 

 

轉自 : http://youngflying.com/2012/09/14/hibernate-batch-processing/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM