有的时候需要一次性执行大批量的SQL,而不是执行一条SQL向数据库提交一次,那么会
用到 IBATIS 的batch提交。
IBATIS的 batch提交也是基于 JDBC的batch功能。
那么我现来写段代码示范一下:
第一步,建立我的测试类。
其中 BabyDO,sexEnum 等类是自己写的,并不重要,只要让程序跑起来,读者可以自己写下。不多讲了,主要讲重点的几个语句。
package com.yajun;
// import 很多JDK给的类
import com.yajun.dataobject.BabyDO;
import com.yajun.enumdemo.SexEnum;
import com.yajun.impl.BabyDAOImpl;
/**
* 专门测试batch操作的
*
* @author yajun
*
*/
public class BatchInsertTest {
private BabyDAOImpl babyDAO = new BabyDAOImpl();
public static void main(String[] args) throws SQLException {
BatchInsertTest test = new BatchInsertTest();
test.insertBaby();
}
// 批量插入婴儿并且插入数据库
private void insertBaby() throws SQLException {
List<BabyDO> babys = new ArrayList<BabyDO>();
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
BabyDO baby = new BabyDO();
baby.setName("乌鸦军");
baby.setSex(SexEnum.Male);
baby.setBirthday(new Date());
baby.setHobby("踢寂寞足球");
baby.setAge(i);
babys.add(baby);
}
int count = babyDAO.insertBatch(babys);
long end = System.currentTimeMillis();
System.out.println("============ 成功插入BABY " + count + "条 =============");
System.out.println("消费时间 " + (end - start));
}
}
第二步,建立BabyDAO的实现类BabyDAOImpl
package com.yajun.impl;
// import 很多JDK给的类
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.yajun.dao.BabyDAO;
import com.yajun.dataobject.BabyDO;
import com.yajun.dataobject.BabyTestDO;
public class BabyDAOImpl implements BabyDAO {
private SqlMapClient client;
public BabyDAOImpl() {
try {
Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
client = SqlMapClientBuilder.buildSqlMapClient(reader);
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
……(省略其他方法)
/**
* 批量添加小孩
*
* @param babys
* @return
* @throws SQLException
*/
public Integer insertBatch(List<BabyDO> babys) throws SQLException {
int count = 0;
try {
// 自己控制事物的开始
client.startTransaction();
client.startBatch();
for (BabyDO babyDO : babys) {
try {
client.insert("insert-baby", babyDO);
} catch (Exception e) {
System.out.println("插入婴儿失败");
}
}
count = client.executeBatch();
} finally {
// 自己控制事物的结束
client.endTransaction();
}
return count;
}
……(省略其他方法)
运行起来的结果:
============ 成功插入BABY 10000条 =============
消费时间 2610
可以看到插入10000条数据只需要2秒钟。
那么这里的关键点是我的注释:需要手工控制事物执行,否则事物会在第一条SQL insert 的时候自动将事物关闭掉。
具体原因的代码请看 IBATIS 源码(主要请注意我加注释的那几句话):
public Object insert(SessionScope sessionScope, String id, Object param) throws SQLException {
Object generatedKey = null;
MappedStatement ms = getMappedStatement(id);
Transaction trans = getTransaction(sessionScope);
// 如果trans为空的华autoStart=true;如果不手工控制事物,那么这里就是为空
boolean autoStart = trans == null;
try {
// 如果autoStart=true,开启事物
trans = autoStartTransaction(sessionScope, autoStart, trans);
SelectKeyStatement selectKeyStatement = null;
if (ms instanceof InsertStatement) {
selectKeyStatement = ((InsertStatement) ms).getSelectKeyStatement();
}
// Here we get the old value for the key property. We'll want it later if for some reason the
// insert fails.
Object oldKeyValue = null;
String keyProperty = null;
boolean resetKeyValueOnFailure = false;
if (selectKeyStatement != null && !selectKeyStatement.isRunAfterSQL()) {
keyProperty = selectKeyStatement.getKeyProperty();
oldKeyValue = PROBE.getObject(param, keyProperty);
generatedKey = executeSelectKey(sessionScope, trans, ms, param);
resetKeyValueOnFailure = true;
}
StatementScope statementScope = beginStatementScope(sessionScope, ms);
try {
ms.executeUpdate(statementScope, trans, param);
}catch (SQLException e){
// uh-oh, the insert failed, so if we set the reset flag earlier, we'll put the old value
// back...
if(resetKeyValueOnFailure) PROBE.setObject(param, keyProperty, oldKeyValue);
// ...and still throw the exception.
throw e;
} finally {
endStatementScope(statementScope);
}
if (selectKeyStatement != null && selectKeyStatement.isRunAfterSQL()) {
generatedKey = executeSelectKey(sessionScope, trans, ms, param);
}
// 如果autoStart为true自动提交事务(提交事务以后,后面的SQL就没有在一个BATCH里面了)
autoCommitTransaction(sessionScope, autoStart);
} finally {
autoEndTransaction(sessionScope, autoStart);
}
return generatedKey;
}
分享到:
相关推荐
### 详细介绍Ibatis的用法 #### Ibatis概述与特点 Ibatis是一个开源的持久层框架,它通过简单的XML配置文件将JavaBean映射到SQL语句上,从而极大简化了对关系数据库的操作。与其他数据库持久层框架如JDO、...
在这个"iBatis Web用法实例"中,我们将深入探讨如何在Web项目中集成并使用iBatis,以及相关的最佳实践。 1. **iBatis 概述**: iBatis 作为轻量级的ORM(对象关系映射)框架,它的核心思想是将SQL与Java代码分离,...
**iBatis的使用步骤** 1. **配置环境**:引入iBatis的jar包,并在项目中配置SqlMapConfig.xml文件,包括数据源、事务管理器等。 2. **编写SQL映射文件**:创建XML文件,定义SQL语句,包括查询、插入、更新和删除等...
Ibatis 提供了一些基本的API,如查询、添加、删除和修改方法。通常,会通过 SqlMapClient 的工厂类创建 SqlMapClient 实例,以管理数据库操作。例如,使用 SqlMapClientBuilder 创建 SqlMapClient 对象,然后执行...
### iBATIS缓存的使用方法 在数据库访问框架iBATIS中,缓存机制是一项重要的功能,它能够显著提高应用程序的性能。本文将详细介绍iBATIS中的缓存使用方法,包括缓存模型的配置、不同类型的缓存控制器以及如何在SQL...
- 在Ibatis的配置文件`SqlMapConfig.xml`中,可以设置`<settings>`标签内的`defaultExecutorType`属性为`BATCH`或`SIMPLE`,以确保每次执行的SQL都是独立的,避免因缓存导致的编码问题。 - 同时,确保你的项目编码...
Ibatis 是一款轻量级的Java持久层框架,它允许开发者将SQL语句与Java代码分离,从而使得数据库访问更加灵活、易于维护。本篇文章将深入探讨Ibatis的核心概念、最佳实践以及与其他框架如Struts和Spring的整合。 1. ...
### IBatis.Net 使用方法详解 #### 一、概述 IBatis.NET是一款开源的数据访问层框架,它能够将对象与数据库中的记录映射起来,并提供了一系列的工具帮助开发者更高效地处理数据访问逻辑。本文将围绕如何下载、编译...
通过这个demo,你可以了解到Ibatis的基本用法,如何编写SQL映射文件,如何设计Mapper接口,以及如何在Java代码中调用这些接口执行数据库操作。同时,也能掌握Ibatis的动态SQL特性,以及如何配合Spring进行更高效的...
当调用这个方法时,iBatis会自动生成如下SQL: ```sql SELECT * FROM users WHERE id IN (1, 2, 3, ...) ``` 注意,`#{ids[index]}`中的`index`是可选的,如果省略,则默认使用集合中的元素。如果需要访问集合中的...
- 使用`SqlMapExecutor`对象的`startBatch()`方法启动批量更新模式。 - 循环遍历待更新的数据集合,使用`update`方法依次执行更新操作。 - 调用`executeBatch()`方法提交所有的更新操作。 4. **示例代码**: ``...
SqlMap接口则封装了SQL语句,提供了数据操作的方法;Executor执行器是整个框架的执行核心,负责处理SQL的执行和结果映射。 二、SqlMapConfig配置解析 iBatis的配置文件SqlMapConfig.xml是系统启动时加载的关键,它...
iBatis动态SQL标签用法 iBatis是Java持久层框架,提供了动态SQL标签来实现动态查询。动态SQL标签可以根据不同的条件生成不同的SQL语句,从而提高查询效率和灵活性。 动态SQL片段 iBatis提供了动态SQL片段的功能,...
以下是对iBATIS简易使用的详细解释: 1. **环境准备**: - **jar文件**:iBATIS框架运行需要依赖一些库文件,包括`log4j`用于日志记录,`ibatis`核心库,以及`jdbc`驱动,这些都需要添加到项目的类路径中。 - **...
2. 执行映射的Statement,iBATIS框架创建PreparedStatement,使用参数对象,执行SQL并从结果集中构建返回对象。 3. 返回结果,如果是更新操作,返回受影响的行数;如果是查询,返回单个对象或对象集合。 五、基础...
- **读取配置文件**:使用 `Resources.getResourceAsReader()` 方法读取配置文件,例如 `CONFIG_FILE_PATH`。 - **创建 SqlSessionFactory**:通过 `SqlSessionFactoryBuilder.build()` 方法创建 `SqlSessionFactory...
以上就是IBatis的基本使用方法和核心概念,通过它可以有效地提升数据库操作的便捷性和灵活性,降低开发成本。在实际项目中,可以根据需求进行扩展和定制,如结合Spring框架实现更高级的整合应用。
以上就是一个简单的Ibatis入门例子,展示了如何使用Ibatis进行数据库查询。实际上,Ibatis还支持动态SQL、结果映射、参数映射等多种高级特性,可以实现更复杂的业务逻辑。例如,你可以通过使用`<if>`、`<choose>`等...
"iBatis开发指南"则是更全面的官方文档,它包含了iBatis的所有特性和使用方法。从中,你可以学习到动态SQL的使用,这是一种强大的特性,允许你在运行时根据条件动态地构建SQL语句。此外,还有关于事务管理、缓存机制...
通过阅读和理解源码,开发者不仅能掌握iBATIS DAO的基本使用,还能深入了解其内部实现,提升数据库操作的技巧和优化能力。同时,添加注释的过程也是深化理解的好方法,有助于在实际项目中更高效地应用iBATIS框架。