ibatis中的的处理方法

spring集成了ibatis的批量提交的功能,我们只要调用API就可以了
首先在你的dao中需要继承org.springframework.orm.ibatis.support.SqlMapClientDaoSupport
然后在代码中调用getSqlMapClientTemplate方法, 获取SqlMapClientTemplate对象,然后做处理

public void insertInfos(List<Info> records) {
        if (null == records || records.size() == 0) {
            return;
        }
        // 执行回调
        SqlMapClientTemplate sqlMapClientTemplate = iBatisDaoLS13.getSqlMapClientTemplate();
        sqlMapClientTemplate.execute(new SqlMapClientCallback() {
            // 实现回调接口
            public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
                // 开始批处理, for循环里面的sql必须一致,否则会创建新的PreparedStatement
                executor.startBatch();
                for (Info info : records) {
                    executor.insert(NAMESPACE + "insertAInfo", info);
                }
                // 执行批处理
                executor.executeBatch();
                return null;
            }
        });
    }

mybatis中的的处理方法

   在程序中,有时候我们需要批量的去操作一些数据,批量的新增、修改、删除,如果是通过for循环一条记录一条记录的去更新无疑效率会比较慢。更佳的做法无疑是采用JDBC对批处理的支持。Mybatis基于JDBC对批处理的支持,也提供了进行数据的批量操作的API,BatchExecutor。下面是一段JDBC进行批量操作的示例代码。

@Test

public void testJDBCBatch() throws SQLException {

String sql = "insert into t_user(name, mobile, email) values(?,?,?)";

try (Connection conn = dataSource.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql);) {

List<User> users = this.getUsers();

for (User user : users) {

pstmt.setString(1, user.getName());

pstmt.setString(2, user.getMobile());

pstmt.setString(3, user.getEmail());

pstmt.addBatch();

}

pstmt.executeBatch();

conn.commit();

}

}

在每一次调用的时候是调用Statement.addBatch()方法,最终所有的参数都传递完了,没有更多的参数时调用Statement.executeBatch()方法进行批量操作。在上一篇博文中我们查看了BatchExecutor的源码,它的核心代码doUpdate()方法,每次被调用的时候都是以handler.batch()结束,而handler.batch()对应的底层代码是调用对应的Statement的addBatch()方法。那它是在什么时候执行executeBatch()呢?

@Override

public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLException {

final Configuration configuration = ms.getConfiguration();

final StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, RowBounds.DEFAULT, null, null);

final BoundSql boundSql = handler.getBoundSql();

final String sql = boundSql.getSql();

final Statement stmt;

if (sql.equals(currentSql) && ms.equals(currentStatement)) {

intlast = statementList.size() - 1;

stmt = statementList.get(last);

handler.parameterize(stmt);//fix Issues 322

BatchResult batchResult = batchResultList.get(last);

batchResult.addParameterObject(parameterObject);

} else {

Connection connection = getConnection(ms.getStatementLog());

stmt = handler.prepare(connection);

handler.parameterize(stmt);    //fix Issues 322

currentSql = sql;

currentStatement = ms;

statementList.add(stmt);

batchResultList.add(new BatchResult(ms, sql, parameterObject));

}

// handler.parameterize(stmt);

handler.batch(stmt);

return BATCH_UPDATE_RETURN_VALUE;

}

它的executeBatch()是在doFlushStatements()方法调用中调用的,它会在当前Executor进行commit时调用,也会在当前Executor第一次执行doQuery()时调用,在这个时候都会调用Executor的flushStatements()方法,而BaseExecutor在执行flushStatements()时最终会调用其doFlushStatements()方法。当然,我们也可以手动的调用SqlSession的flushStatements()方法,其底层实现也会调用对应的BaseExecutor的flushStatements()方法。

@Override

public List<BatchResult> doFlushStatements(boolean isRollback) throws SQLException {

try {

List<BatchResult> results = new ArrayList<BatchResult>();

if (isRollback) {

return Collections.emptyList();

}

for (int i = 0, n = statementList.size(); i < n; i++) {

Statement stmt = statementList.get(i);

BatchResult batchResult = batchResultList.get(i);

try {

batchResult.setUpdateCounts(stmt.executeBatch());

MappedStatement ms = batchResult.getMappedStatement();

List<Object> parameterObjects = batchResult.getParameterObjects();

KeyGenerator keyGenerator = ms.getKeyGenerator();

if (Jdbc3KeyGenerator.class.equals(keyGenerator.getClass())) {

Jdbc3KeyGenerator jdbc3KeyGenerator = (Jdbc3KeyGenerator) keyGenerator;

jdbc3KeyGenerator.processBatch(ms, stmt, parameterObjects);

} else if (!NoKeyGenerator.class.equals(keyGenerator.getClass())) { //issue #141

for (Object parameter : parameterObjects) {

keyGenerator.processAfter(this, ms, stmt, parameter);

}

}

} catch (BatchUpdateException e) {

StringBuilder message = new StringBuilder();

message.append(batchResult.getMappedStatement().getId())

.append(" (batch index #")

.append(i + 1)

.append(")")

.append(" failed.");

if (i > 0) {

message.append(" ")

.append(i)

.append(" prior sub executor(s) completed successfully, but will be rolled back.");

}

throw new BatchExecutorException(message.toString(), e, results, batchResult);

}

results.add(batchResult);

}

return results;

} finally {

for (Statement stmt : statementList) {

closeStatement(stmt);

}

currentSql = null;

statementList.clear();

batchResultList.clear();

}

}

下面是一个使用Mybatis的BatchExecutor进行批量操作的示例。在示例中我们创建了一个使用BatchExecutor的SqlSession,也可以是SqlSessionTemplate,其实现了SqlSession接口,底层通过一个SqlSession代理进行相应的操作。然后在循环中一次调用对应Mapper的新增操作,相当于调用BatchExecutor的doUpdate(),最后调用SqlSession的commit()方法提交事务,在SqlSession的commit()中会调用Executor的commit(),从而导致了executeBatch()的发生。

@Test

public void testExecutor() {

SqlSession session = this.sessionFactory.openSession(ExecutorType.BATCH);

UserMapper mapper = session.getMapper(UserMapper.class);

User user = null;

for (inti = 0; i < 10; i++) {

user = new User();

user.setName("Name_" + i);

user.setEmail("email");

mapper.insert(user);

}

// 批量插入User

session.commit();// 提交事务时批量操作才会写入数据库

session.close();

}

ibatis和mybatis中的BatchExecutor的更多相关文章

  1. xml中${}的使用含义(美元符号大括号,以Spring、ibatis、mybatis为例)

    项目中,经常会在xml中看到这样的写法: <properties resource="properties/database.properties"/> <dat ...

  2. Mybatis中的拦截器

    作者:moshenglv的专栏 拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法. ...

  3. Mybatis 中经典的 9 种设计模式!面试可以吹牛了

    虽然我们都知道有23个设计模式,但是大多停留在概念层面,真实开发中很少遇到.Mybatis源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,能够更深入的理解设计模式. Mybatis至少 ...

  4. Mybatis中9种经典的设计模式!你知道几个?

    虽然我们都知道有23个设计模式,但是大多停留在概念层面,真实开发中很少遇到.Mybatis源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,能够更深入的理解设计模式. Mybatis至少 ...

  5. Mybatis中 SIMPLE、REUSE、BATCH的区别

    Executor分成两大类,一类是CacheExecutor,另一类是普通Executor. 普通类又分为: ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情.它为每个语句的执行 ...

  6. ibatis 和 mybatis

    ibatis 在daoImpl 层 继承 SqlMapClientDaoSupport  实现 dao 层的接口. this.getSqlMapClientTemplate().queryForObj ...

  7. IBatis 2.x 和 MyBatis 3.0.x 的区别(从 iBatis 到 MyBatis)

    从 iBatis 到 MyBatis,你准备好了吗? 对于从事 Java EE 的开发人员来说,iBatis 是一个再熟悉不过的持久层框架了,在 Hibernate.JPA 这样的一站式对象 / 关系 ...

  8. mybatis中foreach的用法(转)

    foreach一共有三种类型,分别为List,[](array),Map三种. foreach属性 属性 描述 item 循环体中的具体对象.支持属性的点路径访问,如item.age,item.inf ...

  9. spring中@param和mybatis中@param使用差别

    spring中@param /** * 查询指定用户和企业关联有没有配置角色 * @param businessId memberId * @return */ int selectRoleCount ...

随机推荐

  1. django进阶版4

    目录 1 Auth模块是什么 2 auth模块常用方法 authenticate() login(HttpRequest, user) logout(request) is_authenticated ...

  2. Elastic Search中Query String常见语法

    1 搜索所有数据timeout参数:是超时时长定义.代表每个节点上的每个shard执行搜索时最多耗时多久.不会影响响应的正常返回.只会影响返回响应中的数据数量.如:索引a中,有10亿数据.存储在5个s ...

  3. 输出单项链表中倒数第k个结点——牛客刷题

    题目描述: 输入一个单向链表,输出该链表中倒数第k个结点 输入.输出描述: 输入说明:1.链表结点个数 2.链表结点的值3.输入k的值 输出说明:第k个结点指针 题目分析: 假设链表长度为n,倒数第k ...

  4. 怎样在 Vue 中使用 事件修饰符 ?

    Vue 中可以通过 v-on 来绑定事件监听函数, 不过事件会有许多额外情况, 比如 是否阻止冒泡 / 是否阻止重载 / 是否限制点击次数 / 是否可以通过按键触发 等等. 这时就需要使用到 事件修饰 ...

  5. IDirect3DSurface9的D3DFORMAT格式

    /* Formats * Most of these names have the following convention: * A = Alpha * R = Red * G = Green * ...

  6. 使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)——第1部分

    原文:使用JWT的ASP.NET CORE令牌身份验证和授权(无Cookie)--第1部分 原文链接:https://www.codeproject.com/Articles/5160941/ASP- ...

  7. 【原创】运维基础之Amplify

    官方:https://www.nginx.com/products/nginx-amplify/ NGINX Amplify is a SaaS‑based monitoring tool for t ...

  8. 题解 P2859 【[USACO06FEB]摊位预订Stall Reservations】

    题目链接: https://www.luogu.org/problemnew/show/P2859 思路: 首先大家会想到这是典型的贪心,类似区间覆盖问题的思路,我们要将每段时间的左端点从小到大排序, ...

  9. Navicat for Mysql报错1251连接不成功Mysql

    第一步:打开Command Line Client   看清楚不是cmd,是在mysql的目录下,你会发现有2个一模一样其实哪个都行 第二步:输入mysql密码回车    就是安装mysql时设置的密 ...

  10. Java虚拟机-------垃圾回收机机制

    概述 jvm中的堆图 在了解 垃圾回收器 之前,首先得了解一下垃圾回收器的几个名词. 1. 吞吐量CPU 用于运行用户代码的时间与 CPU 总消耗时间的比值.比如说虚拟机总运行了 100 分钟,用户代 ...