一、使用动态SQL 中的 Foreach 批量插入

1.MySQL

// 实体类

public class MyUser {
private Integer id;
private String name;
private Integer age;
private Dept dept; public class Dept {
private Integer id;
private String name;
private List<MyUser> myUsers;

SQL

<!-- 一条 SQL -->
<!--public Boolean addMyUsers(@Param("users") List<MyUser> users);-->
<insert id="addMyUsers">
insert into myuser(name,age,did) values
<foreach collection="users" item="user" separator=",">
(#{user.name},#{user.age},#{user.dept.id})
</foreach>
</insert> <!-- 多条 SQL -->
<!-- 一次执行多条 SQL 需在 JDBC 数据库连接属性添加 allowMultiQueries=true -->
<!--public Boolean addMyUsers(List<MyUser> users);-->
<insert id="addMyUsers">
<foreach collection="list" item="user" separator=";">
insert into myuser(name,age,did) values (#{user.name},#{user.age},#{user.dept.id})
</foreach>
</insert>

测试代码

/**
* driver=com.mysql.cj.jdbc.Driver
* url=jdbc:mysql://192.168.8.136:3306/mybatis?allowMultiQueries=true
* username=root
* password=root
*/
public static void main(String[] args) {
SqlSession session = null;
try {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
session = sqlSessionFactory.openSession(); MyUserMapper mapper = session.getMapper(MyUserMapper.class); Dept dept = new Dept(2,null);
MyUser myUser1 = new MyUser(null,"xsa",34,dept);
MyUser myUser2 = new MyUser(null,"fgb",24,dept);
MyUser myUser3 = new MyUser(null,"wdx",18,dept);
List<MyUser> list = new ArrayList<>();
list.add(myUser1);
list.add(myUser2);
list.add(myUser3);
mapper.addMyUsers(list);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (session != null) {
session.close();
}
}
}

2.Oracle

<!-- Oracle数据库批量保存,Oracle不支持 values(),(),()
1、多个insert放在begin - end里面
begin
insert into employees(employee_id,last_name,email)
values(employees_seq.nextval,'test_001','test_001@atguigu.com');
insert into employees(employee_id,last_name,email)
values(employees_seq.nextval,'test_002','test_002@atguigu.com');
end;
2、利用中间表:
insert into employees(employee_id,last_name,email)
select employees_seq.nextval,lastName,email from(
select 'test_a_01' lastName,'test_a_e01' email from dual
union
select 'test_a_02' lastName,'test_a_e02' email from dual
union
select 'test_a_03' lastName,'test_a_e03' email from dual
) -->
<insert id="addEmps" databaseId="oracle">
<!-- oracle第一种批量方式 -->
<foreach collection="emps" item="emp" open="begin" close="end;">
insert into employees(employee_id,last_name,email) values(employees_seq.nextval,#{emp.lastName},#{emp.email});
</foreach> <!-- oracle第二种批量方式 -->
insert into employees(employee_id,last_name,email)
<foreach collection="emps" item="emp" separator="union" open="select employees_seq.nextval,lastName,email from(" close=")">
select #{emp.lastName} lastName,#{emp.email} email from dual
</foreach>
</insert>
<sql id="insertColumn">
<if test="_databaseId=='oracle'">
employee_id,last_name,email
</if>
<if test="_databaseId=='mysql'">
last_name,email,gender,d_id
</if>
</sql>

二、使用 Mybatis 的批量执行器

1.单独使用

public static void main(String[] args) {
SqlSession session = null;
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 获取批量执行器,设置不自动提交(默认 false)
session = sqlSessionFactory.openSession(ExecutorType.BATCH,false); UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User(); long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
user.setName(UUID.randomUUID().toString());
user.setAge(25);
mapper.insertUser(user);
}
long end = System.currentTimeMillis(); //批量:预编译sql一次 ==> 设置参数(1000次)===> 执行(1次)===> 执行时长:889
//非批量:(预编译sql=设置参数=执行)(1000次) ===> 执行时长:8812
System.out.println("执行时长:"+(end-start)); // 使用 JDBC 事务需管理要手动提交事务
session.commit();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (session != null) {
session.close();
}
}
}

2.在 SSM 中使用

首先给容器中添加一个可批量执行的 SqlSession,两种方式

xml 方式

<!--配置一个可以进行批量执行的sqlSession  -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"></constructor-arg>
<constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>

代码方式

/**
* 配置一个可以进行批量执行的 sqlSession
*/
@Bean
public SqlSessionTemplate getSqlSessionTemplate(SqlSessionFactoryBean sqlSessionFactoryBean) throws Exception {
/**
* Simple Executor -- SIMPLE 普通的执行器,默认
* Reuse Executor -执行器会重用预处理语句(prepared statements)
* Batch Executor --批量执行器
*/
SqlSessionTemplate sessionTemplate = new SqlSessionTemplate(sqlSessionFactoryBean.getObject(), ExecutorType.BATCH);
return sessionTemplate;
}

使用批量执行,在 service 中注入即可

// @Autowired
// private SqlSessionTemplate sqlSessionTemplate;
@Autowired
private SqlSession sqlSession; public List<Employee> getEmps(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
return employeeMapper.getEmps();
}

https://www.cnblogs.com/jhxxb/p/10451387.html

Mybatis-批量执行的更多相关文章

  1. springMVC 接收数组参数,mybatis 接收数组参数,mybatis批量插入/批量删除案例

    案例是给一个用户赋予多个权限,多个权限用其对应的主键 id 为参数,组成了 一个id数组,传给springMVC,然后springMVC传给mybatis,然后mybatis批量插入.其实类似的场景还 ...

  2. mybatis批量提交

    之前在做项目时,使用mybatis,批量执行sql,这里简单写下步骤 在配置数据库连接时,加入一个参数,例如 jdbc:mysql://127.0.0.1:3307/mvs-report?allowM ...

  3. mybatis批量插入数据

    Mybatis在执行批量插入时,如果使用的是for循环逐一插入,那么可以正确返回主键id.如果使用动态sql的foreach循环,那么返回的主键id列表,可能为null,这让很多人感到困惑:本文将分析 ...

  4. Mybatis批量insert 返回主键值和foreach标签详解

    Mybatis批量insert 返回主键 Mybatis从3.3.1版本开始,支持批量插入后返回主键ID.首先对于支持自增主键的数据库使用useGenerateKeys和keyProperty,对于不 ...

  5. mybatis批量更新update-设置多个字段值 报错 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near

    mybatis批量更新update-设置多个字段值 2016年08月01日 12:49:26 姚一号 阅读数:29539 标签: mysql mybatis批量更新批量更新allowMultiQuer ...

  6. Mybatis批量删除之Error code 1064, SQL state 42000;

    (一)小小的一次记载. (二):最近的项目都是使用MyBatis,批量新增自己都会写了,但是一次批量删除可把我给折腾了下,写法网上都有,但是照着做就是不行,最后问公司的人,问网友才得到答案,那就是jd ...

  7. 160421、MyBatis批量插入数据

    在程序中封装了一个List集合对象,然后需要把该集合中的实体插入到数据库中,由于项目使用了Spring+MyBatis的配置,所以打算使用MyBatis批量插入,由于之前没用过批量插入,在网上找了一些 ...

  8. mybatis批量保存的两种方式(高效插入)

    知识点:mybatis中,批量保存的两种方式 1.使用mybatis foreach标签 2.mybatis ExecutorType.BATCH 参考博客:https://www.jb51.net/ ...

  9. MyBatis批量插入数据(MySql)

    由于项目需要生成多条数据,并保存到数据库当中,在程序中封装了一个List集合对象,然后需要把该集合中的实体插入到数据库中,项目使用了Spring+MyBatis,所以打算使用MyBatis批量插入,应 ...

  10. mybatis批量update,返回行数为-1

    mybatis批量更新返回结果为-1,是由于mybatis的defaultExExecutorType引起的,    它有三个执行器:SIMPLE 就是普通的执行器:REUSE 执行器会重用预处理语句 ...

随机推荐

  1. 文件比较命令(comp)

    comp命令: // 描述: 逐字节比较两个文件或文件集的内容. 如果在没有参数的情况下使用,comp会提示你输入要比较的文件. // 语法: comp [<Data1>] [<Da ...

  2. iOS Password AutoFill开发指南

    转载请标明来源:https://www.cnblogs.com/zhanggui/p/9431950.html 引言 在<iPhone User Guide for iOS 11.4>这本 ...

  3. 26 python 初学(线程、同步锁、死锁和递归锁)

    参考博客: www.cnblogs.com/yuanchenqi/articles/5733873.html 并发:一段时间内做一些事情 并行:同时做多件事情 线程是操作系统能够进行运算调度的基本单位 ...

  4. SpringMVC处理请求和返回流程

    流程描述:一个url请求,找打指定的requestMapping再返回指定的jsp界面 通过url拿到指定的java方法 HandlerExecutionChain  mappedHandler = ...

  5. 以springMVC为例获取上传视频文件时长

    毕设项目是一个在线学习系统,教师用户有上传视频的功能,在答辩之前赶了一个demo出来,好多功能都写死了,比如课程学习进度就是被我写死在前端的一个变量,最近导师要我把项目打包发给他,这才心慌慌赶紧把这些 ...

  6. PHP性能优化:in_array和isset 在大数组查询中耗时相差巨大,以及巧妙使用array_flip

    今天在PHP业务开发中,发现了一个问题. 两个较大数组(20万+元素),遍历其中一个$a,另一个数组$b用于查找元素. 比如 foreach($a as $val){ if(in_array($xx, ...

  7. HRBUST - 2069-萌萌哒十五酱的衣服~-multiset-lower_bound

    众所周知,十五酱有很多的衣服,而且十五酱东西收拾的非常糟糕. 所以十五酱经常找不到合适的衣服穿,于是她觉得收拾一下屋子,把衣服配成一套一套的~(即一件衬衫一件裤子. 十五酱一共有n件衣服,有衬衫有裤子 ...

  8. Python--day02(编程语言、运行python代码、变量)

    day01主要内容回顾 1.进制转换: 二进制: 1111  0101 1010 十六进制          f        5      a 2.内存分布:堆区 和 栈区 外来人只能访问栈区的数据 ...

  9. C语言 课堂随记

    1.codeblocks中的pow函数会有误差. 自定义pow函数: int pow(int x,int y) { ; ; i<=y; i++) t=t*x; return t; } 2.C库函 ...

  10. webpack4

    本地安装: npm init -y cnpm install webpack webpack-cli webpack-dev-server --save-dev 然后装一些所需要的loader和插件: ...