Mybatis 批處理
來源:互聯網
上載者:User
有的時候,我們需要一次性插入很多的資料或者一次性更新、刪除很多的資料,那麼為了提高效率,我們需要使用批處理來完成。以下將討論Mybatis+Spring如何使用批處理。
首先應該知道Mybatis是Ibatis的升級版,比Ibatis效能更好,這是我採用Mybatis的原因。
Ibatis是支援批處理的:
public void batchAddExamlog(List examlogList) throws SQLException{ SqlMapClient smc=this.getSqlMapClient(); try { smc.startTransaction(); smc.startBatch(); for (Iterator iter = examlogList.iterator(); iter.hasNext();) { Examlog log = (Examlog) iter.next(); smc.update("insertExamlog", log); } smc.executeBatch(); }finally{ smc.commitTransaction(); smc.endTransaction(); } }
Mybatis介面實現批處理:
sessionFactory.openSession(ExecutorType.BATCH,true);//得到session,用於批量update
以上兩種,他們都可以實現批處理。 但是當 Mybatis + Spring整合,且由Spring控制事務時,Mybatis這種批處理是不能使用的。 因為sessionFactory.openSession(ExecutorTypetype);方法會建立一個新的資料庫連接,該串連不受Spring控制,將導致Spring的事務控制失效,它無法利用與當前線程綁定的session。
再看其他方式:
1、Mybatis主設定檔中,加入下面代碼: <configuration> <settings> <setting name="defaultExecutorType" value="BATCH"/> </settings> </configuration> -- 這是個總配置,所有操作都會生效,在任何一個事務中做的更改,在事務結束時提交,該事務內無法讀取自己的操作結果。 -- 它會導致所有方法 insert 無法返回id,update/delete 無法得到影響行數,所以、這個全域設定並不好。
2、配合(1)使用SqlSessionUtils.getSqlSession(sessionFactory).commit();
-- 雖然資料在事務內提交了,但是依然無法獲得自增id
3、mapper檔案中使用foreach標籤拼裝語句
-- 但是sql語句有長度限制,小資料量可以(當然也可以從資料庫設定sql最長限制)。
4、獲得當前串連,使用jdbc進行批處理操作。
-- 這也不好,sql需要寫在其他地方,不能寫在Mapper檔案中。
5、從Spring上下文中,執行個體化兩個SqlSessionTemplate,一個使用批處理方式,一個不使用批處理,程式中適時而用。
-- 無法獲得自增id,且一個事務中不能同時使用兩個SqlSessionTemplate。
6、從原始碼,擴充自己的批處理實現。 1、BatchExecutor類的public List<BatchResult> doFlushStatements() throws SQLException方法最終執行大量操作,它將返回影響資訊。 2、BatchExecutor.doFlushStatements() 方法在 Executor.commit() 方法中被調用。 3、Executor.commit() 在 SqlSession 中調用。 4、SqlSessionFactory 負責建立 SqlSession。
擴充SqlSessionFactory 建立我們定義的 MySqlSession,MySqlSession 最終可以調用到BatchExecutor.doFlushStatements() 獲得影響結果
-- 這種方式需要擴充源碼。
總結了幾種方式,大家在項目中看情況使用吧。