mapper批量插入

2023-11-20

1.常规方式的批量插入

sql语句

int bathNorm(List<Teacher> teacherList);

<insert id="bathNorm" parameterType="Teacher">
        insert into teacher (tname,age) values
        <foreach collection="list" item="teacher" separator="," close=";">
            (#{teacher.tname},#{teacher.age})
        </foreach>
    </insert>

java代码

StudentDao studentDao=null;
    String[] tnameArr = new String[]{"火", "水", "金", "木", "土"};
public void setup(){
        teacherDao= MyBatisTools.getInstance().openSession().getMapper(TeacherDao.class);
         Random random = new Random();
         // 构造测试数据  插入一万条
         for(int i = 0; i < 10000; i++) {
             Teacher teacher = new Teacher();
             int idx = random.nextInt(tnameArr.length);
             teacher.setTname(tnameArr[idx] +"_"+ (i + 1));
             teacher.setAge(i+1);
             testData.add(teacher);
         }
     }

test类

@test
  public void testbathbrom(){
         long start =System.currentTimeMillis();
         int rows=teacherDao.bathNorm(testData);
        System.out.println("插入数据行数:"+rows+"耗时:"+(System.currentTimeMillis()-start));
    }

数据源

jdbc.url=jdbc:mysql://localhost:3306/tushu
jdbc.driver=com.mysql.jdbc.Driver
jdbc.user=root
jdbc.password=root
jdbc.characterEncoding=utf8

xml配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--    引入外部配置-->
    <properties resource="jdbc.properties" />
    <!--    类型别名是为 Java 类型设置一个短的名字。 它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余-->
    <typeAliases>
        <typeAlias type="com.lanou3g.mybaties.bean.Teacher" alias="Teacher" />
        <typeAlias type="com.lanou3g.mybaties.bean.Student" alias="Student"/>
     </typeAliases>
    <!-- 配置不同环境的参数 -->
    <environments default="development">
        <!-- 开发环境数据库、事务配置 -->
        <environment id="development">
            <!-- 事务管理使用JDBC的事务 -->
            <transactionManager type="MANAGED"/>
            <!-- 配置开发环境数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!-- 注解方式       -->
        <mapper resource="mapper/TeacherMapper.xml" />

    </mappers>
</configuration>

配置的类

public class MyBatisTools {

    private static ConcurrentHashMap<String, SqlSessionFactory> factoryMap = new MyConcurrentHashMap();

    private static MyBatisTools myBatisTools;

    private MyBatisTools() {}

    public static MyBatisTools getInstance() {
        if(myBatisTools == null) {
            synchronized (MyBatisTools.class) {
                if(myBatisTools == null) {
                    myBatisTools = new MyBatisTools();
                }
            }
        }
        log.debug("当前一共有: " + factoryMap.size() +"个SqlSessionFactory实例");
        log.debug("他们分别是: " + factoryMap);
        return myBatisTools;
    }

    public SqlSessionFactory getSessionFactory() {
        return getSessionFactory(null);
    }

    public SqlSessionFactory getSessionFactory(String env) {
        try {
            // 1. 读入配置文件
            InputStream in = Resources.getResourceAsStream("mybaties.xml");
            // 2. 构建SqlSessionFactory(用于获取sqlSession)
            SqlSessionFactory sessionFactory = null;
            synchronized (factoryMap) {
                if(factoryMap.containsKey(env)) {
                    return factoryMap.get(env);
                } else {
                    sessionFactory = new SqlSessionFactoryBuilder().build(in, env);
                    factoryMap.put(env, sessionFactory);
                }
            }
            return sessionFactory;
        } catch (Exception e) {
            log.error("初始化SqlSessionFactory失败", e);
            return null;
        }
    }

    public SqlSession openSession() {
        return getSessionFactory(null).openSession();
    }

    public SqlSession openSession(boolean autoCommit) {
        return getSessionFactory(null).openSession(autoCommit);
    }

    public SqlSession openSession(ExecutorType executorType, boolean autoCommit) {
        return getSessionFactory(null).openSession(executorType, autoCommit);
    }
}

/**
 * 继承原生ConcurrentHashMap,处理null key问题
 */
class MyConcurrentHashMap extends ConcurrentHashMap {
    @Override
    public Object put(Object key, Object value) {
        if(key == null) {
            key = "null";
        }
        return super.put(key, value);
    }

    @Override
    public boolean containsKey(Object key) {
        if(key == null) {
            key = "null";
        }
        return super.containsKey(key);
    }

    @Override
    public Object get(Object key) {
        if(key == null) {
            key = "null";
        }
        return super.get(key);
    }
}

teacher类

public class Teacher {
    private Integer id;
    private String tname;
    private Integer age;

    public Teacher() {
    }

    public Teacher(String tname) {
        this.tname = tname;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", tname='" + tname + '\'' +
                ", age=" + age +
                "}\n";
    }
}

这种方式比较快,但是数据库默认上传数据是4M,超过就要修改数据库的默认值,比较有局限性。

2.使用ExecutorType.BATCH方式执行批量操作

配置如上
sql语句

<insert id="insertTeacher" parameterType="Teacher">
       insert into teacher(tname) values (#{tname});
    </insert>

java类

 @Test
    public void testBatchInsertByExecutorType() {
        SqlSessionFactory factory=MyBatisTools.getInstance().getSessionFactory();
        SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false);
        TeacherDao teacherDao = sqlSession.getMapper(TeacherDao.class);
        long start = System.currentTimeMillis();
        int rows = 0;
        int batchSize = 100;
        int count = 0;
        for(Teacher teacher : testData) {
            rows += teacherDao.insertTeacher(teacher);
            count ++;
            if(count % batchSize == 0) {
                sqlSession.flushStatements();
            }
        }
        sqlSession.flushStatements();
        sqlSession.commit();
        sqlSession.close();
        System.out.println(("插入数据行数: " + rows+", 耗时: " + (System.currentTimeMillis() - start)));
    }

这种插入的量没有限制,但是插入的比常规方式的慢。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mapper批量插入 的相关文章

随机推荐

  • ESP32开发阶段启用 Secure Boot 与 Flash encryption

    Secure Boot 与 Flash encryption详情 请参考 https blog csdn net espressif article details 79362094 1 开发环境 AT版本 2 4 0 0 发布 IDF 与
  • git忽略文件地址

    git忽略文件地址 Objective C gitignore gitignore
  • String和StringBuffer的常见用法

    链接 https www nowcoder com questionTerminal fe6b651b66ae47d7acce78ffdd9a96c7 answerType 1 f discussion来源 牛客网 String的用法 ja
  • dubbo配置提供者和消费者

    1 找到对应的文件 提供者 消费者 参考dubbo官网 http dubbo apache org zh cn docs user quick start html
  • 【NLP】第 6 章 :微调预训练模型

    到目前为止 我们已经了解了如何使用包含预训练模型的huggingface API 来创建简单的应用程序 如果您可以从头开始并仅使用您自己的数据来训练您自己的模型 那不是很棒吗 如果您没有大量空闲时间或计算资源可供使用 那么使用迁移学习 是最
  • 连接池

    总结 1 连接池 java对外提供了连接的接口 连接池的存在就省去了每次创建和释放连接 2 连接池的连接条件 1 将commons pool 1 5 6 jar的jar包引进java项目下的lib文件夹 3 用连接池对象代替dao 层的Co
  • TP6.0 自定义命令创建类文件

    一 修改框架核心扩展包 1 新增指令配置项 2 创建逻辑层类文件模板 3 创建 Logic php 文件 4 执行命令 创建逻辑层类文件 二 不用修改框架源码 推荐 1 创建一个自定义命令类文件 以逻辑层类文件为例 2 复制创建模型类的命令
  • 解决 npm或pnpm : 无法加载文件 C:\Users\bts\AppData\Roaming\npm\pnpm.ps1,因为在此系统上禁止运行脚本

    vscode 使用 npm 或 pnpm打开网页时出现此问题 解决方法 点击左下角开始 找到Windows PowerShell 点击右键找到更多 找到以管理员身份运行 输入命令 set ExecutionPolicy RemoteSign
  • 使用禅道 api 添加用户完整流程与分析

    在使用禅道系统时 有时为了方便 需要与其他系统对接 如其他系统添加用户后可以直接同步到禅道系统 而不是在禅道系统重新添加一遍用户 禅道系统提供了二次开发的api 但是里面的内容并不详细 故笔者写这篇文章进行记录 这里先以 postman进行
  • STM32与ESP8266-MQTT固件的应用

    本文以Clion作为编译器 STM32F407作为芯片 通过串口以AT指令与ESP8266 01S进行通信 让其连接到腾讯云物联网平台 一 ESP8266 01S ESP8266 01S原本固件是不支持MQTT的 因此需要在安信可官网去下载
  • mysql union保持原有查询的排序

    摘要 mysql中对union之后的结果进行排序比较简单 但业务中也会遇到需要保持各个union结果集自身的排序情况 本文将介绍一种想要保持union前各个查询结果集的排序规则不变的处理方式 为各个结果集编排独立排序 规则描述与数据准备 数
  • Linux设备驱动入门

    Linux驱动配置 什么是驱动程序 驱动程序是应用层和硬件设备之间的一个软件层 它向应用层提供了一组标准化的调用接口 同时完全隐藏设备的工作细节 无操作系统时的设备驱动 有操作系统时候的设备驱动 有了操作系统之后 设备驱动反而变得更加复杂了
  • 黑白二维数组,判断两个二维数组之间的相似率

    include
  • 排序算法---希尔排序---详解&&代码

    希尔排序 希尔排序 从整体宏观上有序逐步细节到局部的有序 希尔排序是一种改进版的插入排序 普通的插入排序算法中 是从第2个节点开始 依次插入到有序序列中 这种做法虽然 一次成形 但研究发现时间效率上这么做并不划算 希尔排序的时间复杂度为O
  • Maven 父子POM文件 相同依赖不同版本的问题

    Maven 父子POM文件 相同依赖不同版本的问题 默认用父一级的版本 而且子POM文件的版本处会有黄色Warn 解决 增加
  • qt.qpa.plugin: Could not load the Qt platform plugin “xcb“ in

    在运行mmdetection的时候发现qt5里面缺了啥 qt qpa plugin Could not load the Qt platform plugin xcb in 卸载了好多Qt5 重新安装 都没有用 尝试1 sudo gedit
  • PHPExcel 表格导出数据

    PHPExcel开发文档 https www kancloud cn chunyu php basic knowledge 1041088 1 控制器 平台订单 导出 功能 订单查询导出 导出 功能 平台订单 导出 public funct
  • WEB刷题第一天

    今天刷了第一道简单题 学到了万能密码 admin or 1 1 用户名和密码均输入万能密码 buuoj cn check php username admin or 1 1 password admin or 1 1 html5判断用输入密
  • 矩阵求逆算法及程序实现(C++)

    矩阵求逆算法及程序实现 C
  • mapper批量插入

    1 常规方式的批量插入 sql语句 int bathNorm List