176142998

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            116 Posts :: 0 Stories :: 45 Comments :: 0 Trackbacks
          從4個層面分析這部分實現: 
          1. iBatis的基本實現
          2. 基于事務的iBatis的基本實現
          3. 基于事務的Spring+iBatis實現
          4. 基于回調方式的Spring+iBatis實現

          1.iBatis的基本實現

          iBatis通過SqlMapClient提供了一組方法用于批處理實現:
          1. startBatch() 開始批處理
          2. executeBatch() 執行批處理

          代碼如下:
          Java代碼 復制代碼 收藏代碼
          1. public void create(List<Reply> replyList) {   
          2.   
          3.     try {   
          4.         // 開始批處理   
          5.         sqlMapClient.startBatch();   
          6.   
          7.         for (Reply reply: replyList) {   
          8.             // 插入操作   
          9.             sqlMapClient.insert("Reply.create", reply);   
          10.         }   
          11.         // 執行批處理   
          12.         sqlMapClient.executeBatch();   
          13.   
          14.     } catch (Exception e) {   
          15.         e.printStackTrace();   
          16.     }   
          17. }  

          這是基于iBatis的最基本實現,如果你一步一步debug,你會發現:其實,數據庫已經執行了插入操作!
          因此,除了這兩個核心方法外,你還需要開啟事務支持。否則,上述代碼只不過是個空架子!

          2.基于事務的iBatis的基本實現
          事務處理:
          1. startTransaction() 開始事務
          2. commitTransaction() 提交事務
          3. endTransaction() 結束事務


          我們以insert操作為例,把它們結合到一起:
          Java代碼 復制代碼 收藏代碼
          1. public void create(List<Reply> replyList) {   
          2.   
          3.     try {   
          4.         // 開始事務   
          5.         sqlMapClient.startTransaction();   
          6.         // 開始批處理   
          7.         sqlMapClient.startBatch();   
          8.   
          9.         for (Reply reply: replyList) {   
          10.             // 插入操作   
          11.             sqlMapClient.insert("Reply.create", reply);   
          12.         }   
          13.         // 執行批處理   
          14.         sqlMapClient.executeBatch();   
          15.   
          16.         // 提交事務   
          17.         sqlMapClient.commitTransaction();   
          18.   
          19.     } catch (Exception e) {   
          20.         e.printStackTrace();   
          21.     } finally {     
          22.              try {   
          23.             // 結束事務   
          24.             sqlMapClient.endTransaction();   
          25.                 } catch (SQLException e) {   
          26.                          e.printStackTrace();   
          27.                      }   
          28.     }     
          29. }  

          replyList是一個List,要把這個List插入到數據庫,就需要經過這三個步驟:
          1. 開始批處理 startBatch()
          2. 插入      insert()
          3. 執行批處理 executeBatch()

          如果要在Spring+iBatis中進行批處理實現,需要注意使用同一個sqlMapClient!同時,將提交事務的工作交給Spring統一處理!

          3.基于事務的Spring+iBatis實現
          Java代碼 復制代碼 收藏代碼
          1. public void create(List<Reply> replyList) {   
          2.     if (!CollectionUtils.isEmpty(replyList)) {   
          3.         // 注意使用同一個SqlMapClient會話   
          4.         SqlMapClient sqlMapClient = sqlMapClientTemplate.getSqlMapClient();   
          5.   
          6.         try {   
          7.             // 開始事務   
          8.             sqlMapClient.startTransaction();   
          9.             // 開始批處理   
          10.             sqlMapClient.startBatch();   
          11.             for (Reply reply : replyList) {   
          12.                 // 插入操作   
          13.                 sqlMapClient.insert("Reply.create", reply);   
          14.             }   
          15.   
          16.             // 執行批處理   
          17.             sqlMapClient.executeBatch();   
          18.             // 提交事務 交給Spring統一控制   
          19.             // sqlMapClient.commitTransaction();   
          20.   
          21.         } catch (Exception e) {   
          22.             e.printStackTrace();   
          23.         } finally {     
          24.                  try {   
          25.                 // 結束事務   
          26.                 sqlMapClient.endTransaction();   
          27.                     } catch (SQLException e) {   
          28.                              e.printStackTrace();   
          29.                          }   
          30.         }     
          31.     }   
          32. }  

          注意使用同一個sqlMapClient:
          SqlMapClient sqlMapClient = sqlMapClientTemplate.getSqlMapClient();
          如果直接sqlMapClientTemplate執行insert()方法,將會造成異常!

          想想,還有什么問題?其實問題很明顯,雖然解決了批處理實現的問題,卻造成了事務代碼入侵的新問題。 這么做,有點惡心!
          除此之外,異常的處理也很惡心,不能夠簡單的包裝為 DataAccessException 就無法被Spring當作統一的數據庫操作異常做處理。


          4.基于回調方式的Spring+iBatis實現
          如果觀察過Spring的源代碼,你一定知道,Spring為了保持事務統一控制,在實現ORM框架時通常都采用了回調模式,從而避免了事務代碼入侵的可能!
          修改后的代碼如下:
          Java代碼 復制代碼 收藏代碼
          1. @SuppressWarnings("unchecked")   
          2. public void create(final List<Reply> replyList) {   
          3.     // 執行回調   
          4.     sqlMapClientTemplate.execute(new SqlMapClientCallback() {   
          5.         // 實現回調接口   
          6.         public Object doInSqlMapClient(SqlMapExecutor executor)   
          7.                 throws SQLException {   
          8.             // 開始批處理   
          9.             executor.startBatch();   
          10.             for (Reply reply : replyList) {   
          11.                 // 插入操作   
          12.                 executor.insert("Reply.create", reply);   
          13.   
          14.             }   
          15.             // 執行批處理   
          16.             executor.executeBatch();   
          17.   
          18.             return null;   
          19.   
          20.         }   
          21.     });   
          22.   
          23. }  

          注意,待遍歷的參數replyList需要加入final標識!即,待遍歷對象不能修改!
          引用
          public void create(final List<Reply> replyList)

          這樣做,就將事務處理的控制權完全交給了Spring!
          簡述:
          1. SqlMapClientCallback 回調接口
          2. doInSqlMapClient(SqlMapExecutor executor) 回調實現方法
          3. DataAccessException 最終可能拋出的異常
          posted on 2011-04-21 10:15 飛飛 閱讀(957) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 五家渠市| 岗巴县| 鹤庆县| 合作市| 长子县| 商河县| 吴川市| 南靖县| 西乌珠穆沁旗| 萍乡市| 阳西县| 海门市| 瓦房店市| 两当县| 桃源县| 肃宁县| 红安县| 五台县| 广东省| 绥棱县| 老河口市| 七台河市| 宜良县| 金湖县| 清丰县| 克拉玛依市| 嘉祥县| 宁蒗| 宁城县| 江都市| 靖江市| 无棣县| 花垣县| 丹阳市| 光山县| 西丰县| 南木林县| 金阳县| 涡阳县| 灵丘县| 青神县|