Mybatis批量新增的三种实现方式

 更新时间:2024年12月13日 14:15:51   作者:摩尔多0  
文章讲述了在Java中进行批量操作的最佳实践,包括使用MyBatis的ExecutorType.BATCH模式,作者建议根据实际需求选择是否进行批量操作,因为批量操作并不总是能提升性能,且有副作用,如无法获取自增ID等

导入依赖

 <!-- 数据库驱动 -->
        <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无法返回更新、插入条数。这在某型情形下是不符合业务要求的。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java lambda表达式用法总结

    java lambda表达式用法总结

    这篇文章主要介绍了java lamda表达式用法总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • SpringCloud @RefreshScope刷新机制深入探究

    SpringCloud @RefreshScope刷新机制深入探究

    RefeshScope这个注解想必大家都用过,在微服务配置中心的场景下经常出现,他可以用来刷新Bean中的属性配置,那大家对他的实现原理了解吗?它为什么可以做到动态刷新呢
    2023-03-03
  • kotlin之闭包案例详解

    kotlin之闭包案例详解

    这篇文章主要介绍了kotlin之闭包案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • JVM类加载器之ClassLoader的使用详解

    JVM类加载器之ClassLoader的使用详解

    类加载器负责读取Java字节代码,并转换成java.lang.Class类的一个实例的代码模块。本文主要和大家聊聊JVM类加载器ClassLoader的使用,需要的可以了解一下
    2022-10-10
  • 学习Java中的日期和时间处理及Java日历小程序的编写

    学习Java中的日期和时间处理及Java日历小程序的编写

    这篇文章主要介绍了学习Java中的日期和时间处理及Java日历小程序的编写,这个日历小程序仅用简单的算法实现没有用到date类等,但是带有图形界面,需要的朋友可以参考下
    2016-02-02
  • Spring的构造器注入全过程

    Spring的构造器注入全过程

    这篇文章主要介绍了Spring的构造器注入全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-09-09
  • springboot controller无效的处理方案

    springboot controller无效的处理方案

    这篇文章主要介绍了springboot controller无效的处理方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 使用Spring @DependsOn控制bean加载顺序的实例

    使用Spring @DependsOn控制bean加载顺序的实例

    这篇文章主要介绍了使用Spring @DependsOn控制bean加载顺序的实例讲解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • java中Path和ClassPath用法比较

    java中Path和ClassPath用法比较

    在本篇文章里小编给大家分享了关于java中Path和ClassPath用法比较内容,有需要的朋友们学习下。
    2019-01-01
  • java猜数字小游戏案例

    java猜数字小游戏案例

    这篇文章主要为大家详细介绍了java猜数字小游戏案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10

最新评论