java—数据库批量插入数据

一给  金牌会员 | 2024-7-31 18:07:47 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 979|帖子 979|积分 2937

前言

本篇文章将记载几种使用java向mysql数据库中批量插入数据的方法,好比插入1000条,10000条,10万条乃至100万条数据。操作数据库的方式采用Mybatis框架。
输入的数据:
现数据库有一个student表,表中字段如下:

编写student实体类,及其controller和dao层,因为只是插入数据以是不需要加service层。

方法一

最简单的方法就是使用循环,不断执行单条数据的插入指令。
因此在dao中写一个insertStudent方法,并在xml文件中编写sql语句
  1. void insertStudent(Student student);
复制代码
  1.     <insert id="insertStudent" parameterType="com.example.bootdemo.entity.Student">
  2.         insert into student (s_name,s_birth,s_sex) values (#{s_name},#{s_birth},#{s_sex})
  3.     </insert>
复制代码
随后在controller中编写循环条用该方法,好比循环插入1000条数据,代码如下:
  1.     @ResponseBody
  2.     @RequestMapping("/insertstudent")
  3.     public Integer insertStudent(){
  4.         System.out.println("开始插入");
  5.         long start = System.currentTimeMillis();
  6.         /**
  7.          * 依靠循环插入
  8.          */
  9.         for (int i = 0; i < 1000; i++) {
  10.                 Student student = new Student();
  11.                 student.setS_birth("20230206");
  12.                 student.setS_name("zjd");
  13.                 student.setS_sex("男");
  14.                 studentDao.insertStudent(student);
  15.         }
  16.         long end = System.currentTimeMillis();
  17.         System.out.println("耗时:"+(end-start));
  18.         return 1;
  19.     }
复制代码
这种方式虽然可以实现,但是效率比较慢,因为每次执行插入都要执行一次sql,速度很慢。

方法二


在全部要插入的数据放在列表中,并在sql中使用foreach进行批量插入。这样执行一次sql就可以插入很多数据。
xml编写中编写sql
  1.     <insert id="batchInsertStudent" parameterType="java.util.List">
  2.         insert into student (s_name,s_birth,s_sex) values
  3.         <foreach collection="students"  item="student" index="index" separator=",">
  4.             (
  5.              #{student.s_name},
  6.              #{student.s_birth},
  7.              #{student.s_sex}
  8.             )
  9.         </foreach>
  10.     </insert>
复制代码
将数据方法List中执行sql语句。
  1.     @ResponseBody
  2.     @RequestMapping("/insertstudent")
  3.     public Integer insertStudent(){
  4.         System.out.println("开始插入");
  5.         long start = System.currentTimeMillis();
  6.         /**
  7.          * 批量插入,大量数据时不推荐使用
  8.          */
  9.         List<Student> students = new ArrayList<>(count);
  10.         for(int i=0;i<count;i++){
  11.             Student student = new Student();
  12.             student.setS_name("zjd"+i);
  13.             student.setS_birth("20230206");
  14.             student.setS_name("zjd");
  15.             student.setS_sex("男");
  16.             students.add(student);
  17.         }
  18.         studentDao.batchInsertStudent(students);
  19.         long end = System.currentTimeMillis();
  20.         System.out.println("耗时:"+(end-start));
  21.         return 1;
  22.     }
复制代码
这两种方法在数据量很大时都不推荐使用,第一种会很慢,第二种可能会因为数据过多,sql执行失败,直接报错。

方法三

既然第二种在插入大量数据时会报错,那么面临大量数据,我们可以将其分批插入,好比我可以每次直插入3000条数据,执行多次就可以实现大量数据的插入。
代码如下:
  1.     @ResponseBody
  2.     @RequestMapping("/insertstudent")
  3.     public Integer insertStudent() throws InterruptedException {
  4.         System.out.println("开始插入");
  5.         long start = System.currentTimeMillis();
  6.         CountDownLatch countDownLatch = new CountDownLatch(6);
  7.         for(int i=0;i<6;i++){
  8.             List<Student> students = new ArrayList<>(count);
  9.             int tempCount = 0;
  10.             for(int n=0;n<count;n++){
  11.                 if(tempCount==2999){
  12.                     studentDao.batchInsertStudent(students);
  13.                     tempCount=0;
  14.                     students.clear();
  15.                 }
  16.                 Student student = new Student();
  17.                 student.setS_name("zjd"+i);
  18.                 student.setS_birth("20230206");
  19.                 student.setS_name("zjd");
  20.                 student.setS_sex("男");
  21.                 students.add(student);
  22.                 tempCount++;
  23.             }
  24.             studentDao.batchInsertStudent(students);
  25.             long end = System.currentTimeMillis();
  26.             System.out.println("耗时:"+(end-start));
  27.             countDownLatch.countDown();
  28.         }
  29.         countDownLatch.await();
  30.         return 1;
  31.     }
复制代码
这样速度也会比单条循环插入要快很多。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

一给

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表