mybaits 批量插入,及其测试。
1.引入jar
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.25.RELEASE</version> </dependency>
2.因为是在spring和springmvc,maven下作测试,所以测试类代码必须加入以下注解(重点)若不加入,junit提示空指针异常。
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:applicationContext.xml" }) public class FirstRun { @Autowired private SqlSessionTemplate sqlSessionTemplate; }
3.在spring的配置文件中,配置一个SqlSessionTemplate的类。并且把执行类型,设置为batch
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" > <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactorybean"></constructor-arg> <constructor-arg name="executorType" value="BATCH"></constructor-arg> </bean>
4.测试类,重点,在写测试类时,将测试类,写入到src/main/java/cn/taotao/test/,下,而不是src/test/java下。否则出一堆的找不到资源文件错误。
在java中,自动装载sqlSessionTemplate,然后用它取得sessionFactory,然后打开session并设置不自动提交,得到sqlSession对象。然后用sqlSession对象,获取getmapper,然后做插入测试,之后手动提交。最后关闭session。
在参考的尚硅谷的教学资料视频中,这个地方讲错了。他装载引用的private Sqlsession sqlsession,如果用这样,就没法获得getSqlSessionFactory,进而,没法设置手动提交。
5.java代码如下,4万次插入。单位毫秒。实践表明批处理即使有提升,但是效果不大。
普通版本执行时长66825
批处理执行时长57756
原生态批处理执行时长4543
package cn.taotao.test; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.UUID; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import org.junit.runner.RunWith; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.SqlSessionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import cn.taotao.bean.Employee; import cn.taotao.dao.EmployeeMapper; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:applicationContext.xml" }) public class FirstRun { // private SqlSessionTemplate sqlSessionTemplate; @Autowired private SqlSessionTemplate sqlSessionTemplate; @Test public void First() throws IOException, SQLException { SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false); long start = System.currentTimeMillis(); try { EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class); int size = 40000; for (int i = 0; i < size; i++) { mapper.insert(new Employee(UUID.randomUUID().toString().substring(0, 5), "b", "1", 1)); if (i % 1000 == 0 || i == size - 1) { //手动每1000个一提交,提交后无法回滚 sqlSession.commit(); //清理缓存,防止溢出 sqlSession.clearCache(); } } long end = System.currentTimeMillis(); System.out.println("批处理执行时长" + (end - start)); } finally { sqlSession.close(); } } @Autowired private EmployeeMapper empMapper; @Test public void Second() { long start = System.currentTimeMillis(); for (int i = 0; i < 40000; i++) { empMapper.insert(new Employee(UUID.randomUUID().toString().substring(0, 5), "b", "1", 1)); } long end = System.currentTimeMillis(); System.out.println("普通版本执行时长" + (end - start)); } @Test public void Third() throws Exception { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession openSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false); long start = System.currentTimeMillis(); try { EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class); for (int i = 0; i < 40000; i++) { mapper.insert(new Employee(UUID.randomUUID().toString().substring(0, 5), "b", "1", 1)); } openSession.commit(); long end = System.currentTimeMillis(); // 批量保存执行后的时间 System.out.println("原生态批处理执行时长" + (end - start)); } finally { openSession.close(); } } }