定制软件【数据库】实现批量快速插入大量数据的六种方案

一、(MySQL)通过函数/

1、链接

https://www.jb51.net/article/207999.htm

https://blog.csdn.net/FloraCHY/article/details/117792903

2、代码

  1. -- 定制软件进入数据库
  2. use test;
  3. -- 定制软件显示所有表
  4. show tables;
  5. -- 创建majors表
  6. create table majors(id int, major varchar(255));
  7. -- 定制软件定义结束符$
  8. delimiter "$";
  9. -- 定制软件创建存储过程,定制软件定义存储方法
  10. create procedure batchInsert(in args int)
  11. begin
  12. declare i int default 1;
  13. -- 开启事务(重要!不开的话,100w定制软件数据需要论天算)
  14. start transaction;
  15. while i <= args do
  16. insert into majors(id,major) value(i,concat("软件工程-",i));
  17. set i = i+ 1;
  18. end while;
  19. commit;
  20. end
  21. $
  22. -- 调用函数,生成数据
  23. -- 先生成10w条试试,同时输入$, 回车执行
  24. call batchInsert(100000);
  25. $

3、性能

10000定制软件定制软件条数据用了0.9s

100000条,5s执行完

100w条数据用了58s

二、通过jdbc定制软件的批量插入语句(add/executeBatch)

1、链接

http://t.zoukankan.com/lizm166-p-7890168.html

2、代码

  1. //获取要设置的Arp基准的List后,插入Arp基准表中
  2. public boolean insertArpStandardList(List<ArpTable> list) {
  3. Connection conn = null;
  4. PreparedStatement ps = null;
  5. ResultSet rs = null;
  6. //MySql的JDBC连接的url中要加rewriteBatchedStatements参数,并保证5.1.13以上版本的驱动,才能实现高性能的批量插入。
  7. //优化插入性能,用JDBC的addBatch方法,但是注意在连接字符串加上面写的参数。
  8. //例如: String connectionUrl="jdbc:mysql://192.168.1.100:3306/test?rewriteBatchedStatements=true" ;
  9. String sql = "insert into arp_standard(guid, devicebrand, devicename, deviceip, ipaddress, " +
  10. "macaddress, createtime) values(?,?,?,?,?,?,?)";
  11. try{
  12. conn = DBConnection.getConnection();
  13. ps = conn.prepareStatement(sql);
  14. //优化插入第一步设置手动提交
  15. conn.setAutoCommit(false);
  16. int len = list.size();
  17. for(int i=0; i<len; i++) {
  18. ps.setString(1, list.get(i).getGuid());
  19. ps.setString(2, list.get(i).getDeviceBrand());
  20. ps.setString(3, list.get(i).getDeviceName());
  21. ps.setString(4, list.get(i).getDeviceIp());
  22. ps.setString(5, list.get(i).getIpAddress());
  23. ps.setString(6, list.get(i).getMacAddress());
  24. ps.setString(7, list.get(i).getCreateTime());
  25. //if(ps.executeUpdate() != 1) r = false; 优化后,不用传统的插入方法了。
  26. //优化插入第二步插入代码打包,等一定量后再一起插入。
  27. ps.addBatch();
  28. //if(ps.executeUpdate() != 1)result = false;
  29. //每200次提交一次
  30. if((i!=0 && i%200==0) || i==len-1){//可以设置不同的大小;如50,100,200,500,1000等等
  31. ps.executeBatch();
  32. //优化插入第三步提交,批量插入数据库中。
  33. conn.commit();
  34. ps.clearBatch();//提交后,Batch清空。
  35. }
  36. }
  37. } catch (Exception e) {
  38. System.out.println("MibTaskPack->getArpInfoList() error:" + e.getMessage());
  39. return false; //出错才报false
  40. } finally {
  41. DBConnection.closeConection(conn, ps, rs);
  42. }
  43. return true;
  44. }

三、通过多线程执行jdbc过程

1、链接

http://t.zoukankan.com/fangts-p-6813515.html

2、代码

  1. package tenThreadInsert;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.PreparedStatement;
  5. import java.sql.SQLException;
  6. import java.util.Date;
  7. public class MyThread extends Thread{
  8. public void run() {
  9. String url = "jdbc:mysql://127.0.0.1/teacher";
  10. String name = "com.mysql.jdbc.Driver";
  11. String user = "root";
  12. String password = "123456";
  13. Connection conn = null;
  14. try {
  15. Class.forName(name);
  16. conn = DriverManager.getConnection(url, user, password);//获取连接
  17. conn.setAutoCommit(false);//关闭自动提交,不然conn.commit()运行到这句会报错
  18. } catch (ClassNotFoundException e1) {
  19. e1.printStackTrace();
  20. } catch (SQLException e) {
  21. e.printStackTrace();
  22. }
  23. // 开始时间
  24. Long begin = new Date().getTime();
  25. // sql前缀
  26. String prefix = "INSERT INTO test_teacher (t_name,t_password,sex,description,pic_url,school_name,regist_date,remark) VALUES ";
  27. try {
  28. // 保存sql后缀
  29. StringBuffer suffix = new StringBuffer();
  30. // 设置事务为非自动提交
  31. conn.setAutoCommit(false);
  32. // 比起st,pst会更好些
  33. PreparedStatement pst = (PreparedStatement) conn.prepareStatement("");//准备执行语句
  34. // 外层循环,总提交事务次数
  35. for (int i = 1; i <= 10; i++) {
  36. suffix = new StringBuffer();
  37. // 第j次提交步长
  38. for (int j = 1; j <= 100000; j++) {
  39. // 构建SQL后缀
  40. suffix.append("('" +i*j+"','123456'"+ ",'男'"+",'教师'"+",'www.bbb.com'"+",'Java大学'"+",'"+"2016-08-16 14:43:26"+"','备注'" +"),");
  41. }
  42. // 构建完整SQL
  43. String sql = prefix + suffix.substring(0, suffix.length() - 1);
  44. // 添加执行SQL
  45. pst.addBatch(sql);
  46. // 执行操作
  47. pst.executeBatch();
  48. // 提交事务
  49. conn.commit();
  50. // 清空上一次添加的数据
  51. suffix = new StringBuffer();
  52. }
  53. // 头等连接
  54. pst.close();
  55. conn.close();
  56. } catch (SQLException e) {
  57. e.printStackTrace();
  58. }
  59. // 结束时间
  60. Long end = new Date().getTime();
  61. // 耗时
  62. System.out.println("100万条数据插入花费时间 : " + (end - begin) / 1000 + " s"+" 插入完成");
  63. }
  64. }
  65. 测试代码
  66. package tenThreadInsert;
  67. public class Test {
  68. public static void main(String[] args) {
  69. for (int i = 1; i <=10; i++) {
  70. new MyThread().start();
  71. }
  72. }
  73. }

四、一次性插入多条记录

1、原理

MySQL:

INTO Persons (LastName, Address) VALUES ('Wilson', 'Champs-Elysees'),('Gates', 'Champs-Elysees')

Oracle:

insert into 表名 (字段1)

select '1' from dual

union all

select '2' from dual

2、代码

(1)调用

  1. public static Boolean insertManyByOne(int num) {
  2. String sql = GenSqlUtil.genInsManySql(num);
  3. // System.out.println(sql);
  4. jdbcUtils.insertMany(sql);
  5. System.out.println("共插入" + num + "条数据");
  6. return true;
  7. }
  8. public static String genInsManySql(int num) {
  9. String sql = "INSERT INTO TEST.\"ABANK\" ";
  10. for (int i = 0; i < num; i++) {
  11. sql = sql.concat("select '1', 'CH', '9999', 'Zürcher Kantonalbank', " +
  12. "'ZKBKCHZZ80A', ' ', TO_DATE('2009-11-10 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), " +
  13. "TO_DATE('1599-12-31 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), " +
  14. "TO_DATE('2017-07-12 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), " +
  15. "'ADMIN', TO_DATE('1599-12-31 00:00:00', 'SYYYY-MM-DD HH24:MI:SS'), " +
  16. "'ADMIN', TO_TIMESTAMP('2021-04-23 08:54:05.000', 'SYYYY-MM-DD HH24:MI:SS:FF3'), " +
  17. "TO_TIMESTAMP('"+ dateFormat.format(calendar.getTime()) +
  18. "', 'SYYYY-MM-DD HH24:MI:SS:FF3'), " +
  19. "HEXTORAW('"+ RandNumGenUtil.genDefLenStr(15) +"') from dual");
  20. if (i != num -1) {
  21. sql = sql.concat(" union all \");
  22. }
  23. }
  24. return sql;
  25. }

(2)jdbcutils

  1. package com.boulderaitech.utils;
  2. import java.sql.*;
  3. import java.util.Arrays;
  4. public class JDBCUtil {
  5. private String user;
  6. private String pass;
  7. private String url;
  8. private Connection conn = null;//连接对象
  9. private ResultSet rs = null;//结果集对象
  10. private Statement sm = null;
  11. /**
  12. * 构造函数获得数据库用户名和密码
  13. *
  14. * @param user
  15. * @param pass
  16. */
  17. public JDBCUtil(String user, String pass) {
  18. this.user = user;
  19. this.pass = pass;
  20. this.url = "jdbc:oracle:thin:@//172.16.5.162:1521/helowin";
  21. }
  22. /**
  23. * 连接数据库
  24. *
  25. * @return
  26. */
  27. public Connection createConnection() {
  28. String sDBDriver = "oracle.jdbc.driver.OracleDriver";
  29. try {
  30. Class.forName(sDBDriver).newInstance();
  31. conn = DriverManager.getConnection(url, user, pass);
  32. } catch (Exception e) {
  33. System.out.println("数据库连接失败");
  34. e.printStackTrace();
  35. }
  36. return conn;
  37. }
  38. /**
  39. * 关闭数据库
  40. *
  41. * @param conn
  42. */
  43. public void closeConnection(Connection conn) {
  44. try {
  45. if (conn != null) {
  46. conn.close();
  47. }
  48. } catch (Exception e) {
  49. System.out.println("数据库关闭失败");
  50. e.printStackTrace();
  51. }
  52. }
  53. /**
  54. * 插入数据
  55. *
  56. * @param insert 插入语句
  57. * @return
  58. */
  59. public int insert(String insert) {
  60. conn = createConnection();
  61. //String insert = "insert into t_department values('D004','金融部')";
  62. int re = 0;
  63. try {
  64. conn.setAutoCommit(false);//事物开始
  65. sm = conn.createStatement();
  66. re = sm.executeUpdate(insert);
  67. if (re < 0) { //插入失败
  68. conn.rollback(); //回滚
  69. sm.close();
  70. closeConnection(conn);
  71. return re;
  72. }
  73. conn.commit(); //插入正常
  74. sm.close();
  75. closeConnection(conn);
  76. return re;
  77. } catch (Exception e) {
  78. e.printStackTrace();
  79. }
  80. closeConnection(conn);
  81. return 0;
  82. }
  83. /**
  84. * 批量插入数据
  85. */
  86. public int insertBatch(String[] sql) {
  87. conn = createConnection();
  88. //String insert = "insert into t_department values('D004','金融部')";
  89. int re = 0;
  90. try {
  91. conn.setAutoCommit(false);//事务开始
  92. sm = conn.createStatement();
  93. Arrays.stream(sql).forEach(x->{
  94. try {
  95. sm.executeUpdate(x);
  96. } catch (SQLException e) {
  97. e.printStackTrace();
  98. }
  99. });
  100. conn.commit(); //插入正常
  101. sm.close();
  102. closeConnection(conn);
  103. return re;
  104. } catch (Exception e) {
  105. e.printStackTrace();
  106. }
  107. closeConnection(conn);
  108. return 0;
  109. }
  110. /**
  111. * 查询语句
  112. * 返回结果集
  113. *
  114. * @param select
  115. * @return
  116. */
  117. public ResultSet selectSql(String select) {
  118. conn = createConnection();
  119. try {
  120. sm = conn.createStatement();
  121. rs = sm.executeQuery(select);
  122. return rs;
  123. } catch (Exception e) {
  124. e.printStackTrace();
  125. }
  126. return null;
  127. }
  128. /**
  129. * 根据结果集输出
  130. *
  131. * @param rs
  132. */
  133. public void printRs(ResultSet rs) {
  134. int columnsCount = 0;
  135. boolean f = false;
  136. try {
  137. if (!rs.next()) {
  138. return;
  139. }
  140. ResultSetMetaData rsmd = rs.getMetaData();
  141. columnsCount = rsmd.getColumnCount();//数据集的列数
  142. for (int i = 0; i < columnsCount; i++) {
  143. System.out.print(rsmd.getColumnLabel(i + 1) + "/n"); //输出列名
  144. }
  145. System.out.println();
  146. while (!f) {
  147. for (int i = 1; i <= columnsCount; i++) {
  148. //System.out.print(rs.getString(i)+"/t");
  149. //逻辑处理
  150. String name = rs.getString("NAME");
  151. System.out.print(rs.getString("NAME") + "/n");
  152. }
  153. System.out.println();
  154. if (!rs.next()) {
  155. f = true;
  156. }
  157. }
  158. rs.close();
  159. } catch (Exception e) {
  160. e.printStackTrace();
  161. }
  162. closeConnection(conn);
  163. }
  164. /**
  165. * 插入数据
  166. *
  167. * @param update 更新语句
  168. * @return
  169. */
  170. public int update(String update) {
  171. conn = createConnection();
  172. //String insert = "insert into t_department values('D004','金融部')";
  173. int re = 0;
  174. try {
  175. conn.setAutoCommit(false);//事物开始
  176. sm = conn.createStatement();
  177. re = sm.executeUpdate(update);
  178. if (re < 0) { //插入失败
  179. conn.rollback(); //回滚
  180. sm.close();
  181. closeConnection(conn);
  182. return re;
  183. }
  184. conn.commit(); //插入正常
  185. sm.close();
  186. closeConnection(conn);
  187. return re;
  188. } catch (Exception e) {
  189. e.printStackTrace();
  190. }
  191. closeConnection(conn);
  192. return 0;
  193. }
  194. public int insertMany(String sql) {
  195. conn = createConnection();
  196. int re = 0;
  197. try {
  198. conn.setAutoCommit(false);//事物开始
  199. sm = conn.createStatement();
  200. re = sm.executeUpdate(sql);
  201. if (re < 0) { //插入失败
  202. conn.rollback(); //回滚
  203. sm.close();
  204. closeConnection(conn);
  205. return re;
  206. }
  207. conn.commit(); //插入正常
  208. sm.close();
  209. closeConnection(conn);
  210. return re;
  211. } catch (Exception e) {
  212. e.printStackTrace();
  213. }
  214. closeConnection(conn);
  215. return 0;
  216. }
  217. }

五、通过定时器实现定时执行

  1. public static Boolean insertBatchFixTime(int numOfInsert, int timePerEpoch) {
  2. Timer timer = new Timer();
  3. timer.schedule(new TimerTask() {
  4. @Override
  5. public void run() {
  6. insertManyByOne(numOfInsert);
  7. }
  8. }, 0L, timePerEpoch * 1000L);
  9. System.out.println("当前线程:" + Thread.currentThread().getName() + " 当前时间" + LocalDateTime.now());
  10. return true;
  11. }

六、通过循环实现批量插入

  1. public static Boolean insertBatchFixCircle(int numOfEachInsert, int numOfEpoch) {
  2. LocalDateTime start = LocalDateTime.now();
  3. for (int i = 0; i < numOfEpoch; i++) {
  4. insertManyByOne(numOfEachInsert);
  5. }
  6. System.out.println("共插入" + numOfEachInsert * numOfEpoch+"条数据");
  7. LocalDateTime end = LocalDateTime.now();
  8. System.out.println("共耗时" + Duration.between(start, end).toMillis() + "ms");
  9. return true;
  10. }
网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发