导入依赖
<!-- 数据库驱动 --> <dependency> <groupid>mysql</groupid> <artifactid>mysql-connector-java</artifactid> <version>5.1.48</version> </dependency> <!-- lombok --> <dependency> <groupid>org.projectlombok</groupid> <artifactid>lombok</artifactid> </dependency> <!-- mybatis-plus --> <dependency> <groupid>com.baomidou</groupid> <artifactid>mybatis-plus-boot-starter</artifactid> <version>3.0.5</version> </dependency> <!-- web--> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <!--test--> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-test</artifactid> <scope>test</scope> </dependency>
dao
@repository // 代表持久层 public interface deptmapper { int adddept(dept dept); int foreachadd(list<dept> list); }
记得在启动类上加
@mapperscan(“com.example.demo.dao”)
deptmapper.xml
<?xml version="1.0" encoding="utf-8" ?> <!doctype mapper public "-//mybatis.org//dtd mapper 3.0//en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.demo.dao.deptmapper"> <!--普通新增--> <insert id="adddept" parametertype="com.example.demo.pojo.dept"> insert into dept (dname, db_source) values (#{dname},#{dbsource}) </insert> <!--foreachmysql写法--> <insert id="foreachadd" parametertype="java.util.list"> insert into dept ( dname, db_source ) values <foreach collection="list" item="dept" index="index" separator="," > ( #{dept.dname,jdbctype=varchar}, #{dept.dbsource,jdbctype=varchar} ) </foreach> </insert> </mapper>
实体类
@data @allargsconstructor @noargsconstructor public class dept { private long deptno; private string dname; private string dbsource; }
配置文件
# mysql 5 驱动不同 com.mysql.jdbc.driver # mysql 8 驱动不同com.mysql.cj.jdbc.driver、需要增加时区的配置 servertimezone=gmt%2b8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.url=jdbc:mysql://localhost:3306/db01?usessl=false&useunicode=true&characterencoding=utf-8&servertimezone=gmt%2b8 spring.datasource.driver-class-name=com.mysql.jdbc.driver mybatis-plus.mapper-locations=classpath:mapping/*mapper.xml
核心测试类
@springboottest class demoapplicationtests { @autowired private deptmapper deptmapper; //测试数据 public list<dept> textdata(){ arraylist<dept> deptlist = new arraylist<>(); for (int i = 0; i < 1000; i++) { dept dept = new dept(); dept.setdname("foreach"); dept.setdbsource("db02"); deptlist.add(dept); } return deptlist; } // 循环插入 @test public void add(){ list<dept> textdata = textdata();//测试数据 long start = system.currenttimemillis();//开始时间 for(dept dept : textdata){ deptmapper.adddept(dept); } system.out.println(system.currenttimemillis() - start);//统计时间 } // foreach标签 @test public void foreach(){ list<dept> textdata = textdata();//测试数据 long start = system.currenttimemillis();//开始时间 deptmapper.foreachadd(textdata); system.out.println(system.currenttimemillis() - start);//统计时间 } @autowired private sqlsessionfactory sqlsessionfactory; @test public void testinsertbatch(){ list<dept> textdata = textdata();//测试数据 long start = system.currenttimemillis();//开始时间 sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch,false); deptmapper studentmappernew = sqlsession.getmapper(deptmapper.class); textdata.stream().foreach(student -> studentmappernew.adddept(student)); sqlsession.commit(); sqlsession.clearcache(); system.out.println(system.currenttimemillis() - start);//统计时间 } }
总结
其实实际意义上来说,包括在程序里面for循环还是在sql里面for循环都不算是批量操作。
只有将executortype设置为batch模式才是真正意义上的批量操作。
并且事实证明在sql循环时设置batch与否其实执行时间差别不是很大,几乎可以忽略不计。
所以其实如果不是特别要求性能。可以直接在sql中使用for循环即可。
谨慎使用batch,如果需要使用batch,请在需要的函数上面设置batch,不要全局使用。
因为batch也是有副作用的。比如在insert操作时,在事务没有提交之前,是没有办法获取到自增的id,此外,对于update、delete无法返回更新、插入条数。这在某型情形下是不符合业务要求的。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论