当前位置:首页 > 开发 > 编程语言 > Spring > 正文

转spring中ibatis的批处理方式

发表于: 2011-11-30   作者:dongwujing   来源:转载   浏览次数:
摘要: 最近做一个小项目,用到Spring+iBatis。突然遇到一个很久远,却很实在的问题:在Spring下怎么使用iBatis的批处理实现? 大概是太久没有写Dao了,这部分真的忘得太干净了。 从4个层面分析这部分实现: iBatis的基本实现 基于事务的iBatis的基本实现 基于事务的Spring+iBatis实现 基于回调方式的Spring+iBatis实现 1.i

最近做一个小项目,用到Spring+iBatis。突然遇到一个很久远,却很实在的问题:在Spring下怎么使用iBatis的批处理实现?

大概是太久没有写Dao了,这部分真的忘得太干净了。

从4个层面分析这部分实现:
iBatis的基本实现
基于事务的iBatis的基本实现
基于事务的Spring+iBatis实现
基于回调方式的Spring+iBatis实现


1.iBatis的基本实现
iBatis通过SqlMapClient提供了一组方法用于批处理实现:
startBatch() 开始批处理
executeBatch() 执行批处理

代码如下:
Java代码
public void create(List<Reply> replyList) { 
 
    try { 
        // 开始批处理 
        sqlMapClient.startBatch(); 
 
        for (Reply reply: replyList) { 
            // 插入操作 
            sqlMapClient.insert("Reply.create", reply); 
        } 
        // 执行批处理 
        sqlMapClient.executeBatch(); 
 
    } catch (Exception e) { 
        e.printStackTrace(); 
    } 


这是基于iBatis的最基本实现,如果你一步一步debug,你会发现:其实,数据库已经执行了插入操作!
因此,除了这两个核心方法外,你还需要开启事务支持。否则,上述代码只不过是个空架子!
2.基于事务的iBatis的基本实现
事务处理:
startTransaction() 开始事务
commitTransaction() 提交事务
endTransaction() 结束事务


我们以insert操作为例,把它们结合到一起:
Java代码
public void create(List<Reply> replyList) { 
 
    try { 
        // 开始事务 
        sqlMapClient.startTransaction(); 
        // 开始批处理 
        sqlMapClient.startBatch(); 
 
        for (Reply reply: replyList) { 
            // 插入操作 
            sqlMapClient.insert("Reply.create", reply); 
        } 
        // 执行批处理 
        sqlMapClient.executeBatch(); 
 
        // 提交事务 
        sqlMapClient.commitTransaction(); 
 
    } catch (Exception e) { 
        e.printStackTrace(); 
    } finally {   
             try { 
            // 结束事务 
            sqlMapClient.endTransaction(); 
                } catch (SQLException e) { 
                         e.printStackTrace(); 
                     } 
    }   


replyList是一个List,要把这个List插入到数据库,就需要经过这三个步骤:
开始批处理 startBatch()
插入      insert()
执行批处理 executeBatch()
如果要在Spring+iBatis中进行批处理实现,需要注意使用同一个sqlMapClient!同时,将提交事务的工作交给Spring统一处理!

3.基于事务的Spring+iBatis实现
Java代码
public void create(List<Reply> replyList) { 
    if (!CollectionUtils.isEmpty(replyList)) { 
        // 注意使用同一个SqlMapClient会话 
        SqlMapClient sqlMapClient = sqlMapClientTemplate.getSqlMapClient(); 
 
        try { 
            // 开始事务 
            sqlMapClient.startTransaction(); 
            // 开始批处理 
            sqlMapClient.startBatch(); 
            for (Reply reply : replyList) { 
                // 插入操作 
                sqlMapClient.insert("Reply.create", reply); 
            } 
 
            // 执行批处理 
            sqlMapClient.executeBatch(); 
            // 提交事务 交给Spring统一控制 
            // sqlMapClient.commitTransaction(); 
 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } finally {   
                 try { 
                // 结束事务 
                sqlMapClient.endTransaction(); 
                    } catch (SQLException e) { 
                             e.printStackTrace(); 
                         } 
        }   
    } 


注意使用同一个sqlMapClient:
SqlMapClient sqlMapClient = sqlMapClientTemplate.getSqlMapClient();
如果直接sqlMapClientTemplate执行insert()方法,将会造成异常!

想想,还有什么问题?其实问题很明显,虽然解决了批处理实现的问题,却造成了事务代码入侵的新问题。 这么做,有点恶心!
除此之外,异常的处理也很恶心,不能够简单的包装为 DataAccessException 就无法被Spring当作统一的数据库操作异常做处理。


4.基于回调方式的Spring+iBatis实现
如果观察过Spring的源代码,你一定知道,Spring为了保持事务统一控制,在实现ORM框架时通常都采用了回调模式,从而避免了事务代码入侵的可能!
修改后的代码如下:
Java代码
@SuppressWarnings("unchecked") 
public void create(final List<Reply> replyList) { 
    // 执行回调 
    sqlMapClientTemplate.execute(new SqlMapClientCallback() { 
        // 实现回调接口 
        public Object doInSqlMapClient(SqlMapExecutor executor) 
                throws SQLException { 
            // 开始批处理 
            executor.startBatch(); 
            for (Reply reply : replyList) { 
                // 插入操作 
                executor.insert("Reply.create", reply); 
 
            } 
            // 执行批处理 
            executor.executeBatch(); 
 
            return null; 
 
        } 
    }); 
 


注意,待遍历的参数replyList需要加入final标识!即,待遍历对象不能修改!
引用public void create(final List<Reply> replyList)
这样做,就将事务处理的控制权完全交给了Spring!
简述:
SqlMapClientCallback 回调接口
doInSqlMapClient(SqlMapExecutor executor) 回调实现方法
DataAccessException 最终可能抛出的异常

通过上述修改,最终能够解决第三种实现方式中的种种不足!

Spring对iBatis提供的支持还是不够完善,即便是现在最新的Spring3.0.4。最开始,本打算用Spring3.0+iBatis3.0,结果Spring报错,说找不到“com.ibatis.xxxxx”完全是iBatis2.x的包路径!汗颜~ 还是Hibernate比较得宠!

转spring中ibatis的批处理方式

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
1.需求说明 实现用户通过数据库验证登录需求,采用Myeclipse+Tomcat 6.0+Mysql 5.0+JDK 1.6 2.数据
前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一
前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一
AOP:面向切面、面向方面、面向接口是一种横切技术 横切技术运用: 1.事务管理: (1)数据库事务:(2)编
前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直
spring + ibatis 多数据源事务(分布式事务)管理配置方法(转) 1、我先要给大家讲一个概念:spring
1、我先要给大家讲一个概念:spring 的多数据源事务,这是民间的说法。官方的说法是:spring 的分布
随着开发团队转投Google Code旗下,ibatis3.x正式更名为Mybatis 10.3 Spring对IBatis的支持 Spring对
这两天一直在研究ibatis与spring的整合 一个小小的demo搞的我头晕目眩的,但程序一旦跑起来了,突然
前几天自己利用下班的时间写了一下spring与IBatis的工程配置,整个工程分为三层:DAO, SERVICE, CONT
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号