Mybatis-批量执行

时间:2023-03-09 14:54:51
Mybatis-批量执行

一、使用动态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();
}
}
}

Mybatis-批量执行

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