MyBatis 批量操作

MyBatis 批量操作

在业务操作中有时候需要有批量插入的操作,MyBatis Github上的 FAQ1 的中有关于批量插入的示例:

首先,创建一个简单的插入语句:

<insert id="insertName">
  insert into names (name) values (#{value})
</insert>

然后在 Java 代码中执行批量操作:

List<String> names = new ArrayList<String>();
names.add("Fred");
names.add("Barney");
names.add("Betty");
names.add("Wilma");

SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {
  NameMapper mapper = sqlSession.getMapper(NameMapper.class);
  for (String name : names) {
    mapper.insertName(name);
  }
  sqlSession.commit();
} finally {
  sqlSession.close();
}

示例中的操作是 insert,同理 update、delete 等的操作也一样,要点是事务提交一次。

目前的数据库有多种,各个数据库批量插入的方式不一样,但是对于单条插入然后去循环的方式是都支持的,所以 MyBatis 做了一个共通的实例,将执行类型设置ExecutorType.BATCH,批量去提交事务。

示例中的核心在于创建一个操作批量事物的SqlSession,在纯 MyBatis 中 SqlSession 的获取方式为:

InputStream in=Resources.getResourceAsStream("applicationContext.xml");  
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);   
SqlSession sqlsession=factory.openSession();  

查看 Mybatis 中可看到默创建的事务为简单事务: ExecutorType.SIMPLE,批量插入要修改事务类型。

Java 程序处理

在后续的开发中,MyBatis 常与其他框架一起使用,最常见的是 SSM(Spring+SpringMVC+Mybatis) 的整合,通常对数据库事务的操作就交给Spring 去处理了。此时如果有大量数据需要插入,利用循环去 mapper.inset(entity) 也可以解决问题,但是每执行一次都需要开启一个新的事务,对资源的消耗比较大。所以,要采用其他的更优化的方案。

在 Spring 中不用关心 SqlSession 是如何创建销毁的,在applicationContext.xml中配置响应的 SqlsessionFactory 即可。

<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource"/>
  <property name="configLocation" value="classpath:mybatis.xml"/>
</bean>

如果要在 Java 中去控制事务类型,可通过注入 SqlSeesionFactory 的方式显示的获取 SqlSession,

@Autowired
private SqlSessionFactoryBean sqlSessionFactory;
……
SqlSession sqlSession=sqlSessionFactory.getObject().openSession(ExecutorType.BATCH);

获取到 SqlSession 之后在仿照示例中的代码写就可以了。

SQL 拼接处理

另一种方式是通过动态拼接 SQL 的形式去批量插入,这是的主要工作是在数据库那一端进行的。各个数据库批量插入的方式不一样,以下举最常见的两个数据库 MySQL 与 Oracle,其他的数据库欢迎补充。

Dao 中的代码:

public interface userDao{
  public void insertBatch(@Param("userList") List userList);
}

MySQL

MySQL 支持如下类型的 SQL 语句:

insert into users(username,age) values('zhangsan'18),('liming',20),('fengyu',23);

上述 SQL 是 MySQL 特有的,可在*.xml 文件中去执行拼接,

<insert id="insertBatch" parameterType="java.util.List">  
  insert into users(username,age) values
  <foreach collection="userList" item="item" index="index"  separator=",">  
   (#{item.username},#{item.age})
  </foreach>  
</insert> 

Oracle

Oracle 不支持 MySQL 那种写法,但是他也有自己的其他语句来实现这样的功能:

Oracle 中可以使用 insert all,insert first ,union all 等语句去执行批量的事务操作。

union all:

<insert id="insertBatch" parameterType="java.util.List">  
  insert into users(username,age) 
  <foreach collection="freeNumberList" item="item" index="index"  separator="union all">  
    select #{item.username},#{item.age} from dual
  </foreach>  
</insert> 

insert all:

<insert id="insertBatch" parameterType="java.util.List">  
  insert all 
  <foreach collection="freeNumberList" item="item" index="index"> 
   into users(username,age) values(#{item.username},#{item.age})
  </foreach>  
  select 1 from dual
</insert> 

insert first 与 insert all 区别在于可以加上 where 条件。
若想了解更多 MyBatis 文档,请移步:Mybatis Docs


  1. Frequently Asked Questions 常见问题解答
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值