知識點:mybatis中,批量保存的兩種方式
1.使用mybatis foreach標簽
2.mybatis ExecutorType.BATCH
參考博客:https://www.jb51.net/article/91951.htm
一:使用mybatis foreach標簽
具體用法如下:
<!-- 批量保存(foreach插入多條數據兩種方法)
int addEmpsBatch(@Param("emps") List<Employee> emps); -->
<!-- MySQL下批量保存,可以foreach遍歷 mysql支持values(),(),()語法 --> //推薦使用
<insert id="addEmpsBatch">
INSERT INTO emp(ename,gender,email,did)
VALUES
<foreach collection="emps" item="emp" separator=",">
(#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
</foreach>
</insert>
<!-- 這種方式需要數據庫連接屬性allowMutiQueries=true的支持 --> //在jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true
<!-- <insert id="addEmpsBatch"> 后加上allowMultiQueries=true
<foreach collection="emps" item="emp" separator=";"> 表示可以多次執行insert into語句,中間;不會錯
INSERT INTO emp(ename,gender,email,did)
VALUES(#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
</foreach>
</insert> -->
二:mybatis ExecutorType.BATCH
Mybatis內置的ExecutorType有3種,默認為simple,該模式下它為每個語句的執行創建一個新的預處理語句,單條提交sql;而batch模式重復使用已經預處理的語句,並且批量執行所有更新語句,顯然batch性能將更優; 但batch模式也有自己的問題,比如在Insert操作時,在事務沒有提交之前,是沒有辦法獲取到自增的id,這在某型情形下是不符合業務要求的
具體用法如下:
@Test //批量保存方法測試
public void testBatch() throws IOException{
SqlSessionFactory sqlSessionFactory=getSqlSessionFactory();
//可以執行批量操作的sqlSession
SqlSession openSession=sqlSessionFactory.openSession(ExecutorType.BATCH);
//批量保存執行前時間
long start=System.currentTimeMillis();
try{
EmployeeMapper mapper= openSession.getMapper(EmployeeMapper.class);
for (int i = 0; i < 1000; i++) {
mapper.addEmp(new Employee(UUID.randomUUID().toString().substring(0,5),"b","1"));
}
openSession.commit();
long end= System.currentTimeMillis();
//批量保存執行后的時間
System.out.println("執行時長"+(end-start));
//批量 預編譯sql一次==》設置參數==》10000次==》執行1次 677
//非批量 (預編譯=設置參數=執行 )==》10000次 1121
}finally{
openSession.close();
}
}
mapper和mapper.xml如下:
public interface EmployeeMapper {
//批量保存員工
public Long addEmp(Employee employee);
}
<mapper namespace="com.agesun.mybatis.dao.EmployeeMapper"
<!--批量保存員工 -->
<insert id="addEmp">
insert into employee(lastName,email,gender)
values(#{lastName},#{email},#{gender})
</insert>
</mapper>
三:補充:mybatis ExecutorType.BATCH 在SSM框架中的用法
(1)在全局配置文件applcationContext.xml中加入
<!-- 配置一個可以批量執行的sqlSession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
<constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>
(2)在serviceImpl中加入
@Autowired
private SqlSession sqlSession;
//批量保存員工
@Override
public Integer batchEmp() {
// TODO Auto-generated method stub
//批量保存執行前時間
long start=System.currentTimeMillis();
EmployeeMapper mapper= sqlSession.getMapper(EmployeeMapper.class);
for (int i = 0; i < 10000; i++) {
mapper.addEmp(new Employee(UUID.randomUUID().toString().substring(0,5),"b","1"));
}
long end= System.currentTimeMillis();
long time2= end-start;
//批量保存執行后的時間
System.out.println("執行時長"+time2);
return (int) time2;
}