【背景】在项目中遇到一个批量插入数据的需求,由于之前写过的sql语句都是插入一个对象一条数据,于是去网上搜关键词 "sql批量插入"、"mysql批量插入"等,搜到的答案不外乎这三种:

1.逐条执行,在for循环里写insert插入语句

这种方法显然性能还差,不符合常理,遂淘汰。

2.批量执行

INSERT INTO table ( "clo1", "col2", "col3", "col4", "col5" )
VALUES
( 1, 10, NULL, '2019-12-19 13:38:35', '新年活动16张卡券'),
( 2, 11, NULL, '2019-12-19 15:05:13', '圣诞活动11张卡券'),
( 3, 12, NULL, '2019-12-19 15:05:13', '圣诞活动12张卡券'),
( 4, 13, NULL, '2019-12-19 15:05:13', '圣诞活动13张卡券');

这样写的话,虽然可以实现需求,但是如果有批量插入几十甚至上百条数据,这样在代码里要拼接很多条动态数据,代码不美观不规范,也不利于后期维护等,所以这种方法也没有采用。

3.使用存储过程

具体业务逻辑大家自己组合一下就可以。

delimiter $$$
create procedure zqtest()
begin
declare i int default 0;
set i=0;
start transaction;
while i<80000 do//your insert sql
set i=i+1;
end while;
commit;
end
$$$
delimiter;
call zqtest();

由于本人之前是做前端的,对存储过程了解的不怎么深入,也放弃了这种方法。

后面去node官方文档和mysql官方文档也没有找到批量插入数据的方法,于是换了一个关键词,搜“node mysql批量插入”终于找到一篇符合需求的文章了,这里说一下有时候学会搜索关键词也是一种技能吧。


在文章开始之前,我们先说下node.js中的mysql批量插入的方法,我们可以使用如下方法批量插入:

var mysql = require('mysql')var values = [[1, 'hu', 2],[2, 'ke', 0],[3, 'yi', 1]
] // 一个二维数组的数据结构var connection = mysql.createConnection({  host: 'localhost', // 连接的服务器port: 3306, // mysql服务运行的端口database: 'gis', // 选择的库user: 'root', // 用户名password: 'root' // 用户密码
})connection.connect() // 创建一个mysql的线程var insertsql = 'insert into t_gis_road_node(node_id, node_name, node_type) values ?'connection.query(insertsql, [values],(err, results, fields) => { if (err) { console.log('INSERT ERROR - ', err.message);throw err}connection.destroy();console.log("INSERT SUCCESS");
})

于是我就想是否可以使用类似的方式来进行批量更新呢,如果可以的话无疑是十分方便的,我写了以下代码进行测试:

var values = [['hu', 1],['li', 2],['kes', 3]
]var sql = 'update test_name set name = ? where id = ?';connection.query(sql, [values], (err, results, fields) => {if (err) { console.log('UPDATE ERROR - ', err.message);throw err}console.log(results)
})connection.end()

然而,这样写是不行的,报错了

经过测试,如下更新方式是可以的,但是这种写法无法执行多条更新语句:

var sql = 'update test_name set name = ? where id = ?';connection.query(sql, ['kes', 3], (err, results, fields) => {if (err) { console.log('UPDATE ERROR - ', err.message);throw err}console.log(results)
})connection.end()

那么,如何能够同时执行多条更新语句来进行批量更新呢?如下介绍三种方法,如果还有其它方法,欢迎大家留言补充

1,forEach方法
这种方法的思想是通过循环调用connection.query的方式来达到批量更新的目的:

var values = [['hus', 1],['lis', 2],['kess', 3]
]var sql = 'update test_name set name = ? where id = ?';values.forEach((item, index)=>{connection.query(sql, item, (err, results, fields) => {if (err) { console.log('UPDATE ERROR - ', err.message);throw err}console.log(results)})
})connection.end(function(err){console.log('all is ok')
});

使用forEach本质上不能算批量更新,它只是通过多次调用来达到目的,这种方法有个致命的缺陷,就是很难监听到所有更新都执行完的回调,这时就需要我们用到connection.end的回调函数。如上,在执行完所有的更新之后,控制台会输出 all is ok

2,使用insert into … on duplicate key update

mysql有个神奇的语法:insert into ... on duplicate key update,该语法在insert的时候,如果insert的数据会引起唯一索引(包括主键索引)的冲突,即这个唯一值重复了,则不会执行insert操作,而执行后面的update操作。我们通过这个特性就可以利用批量insert的方法来进行批量更新,代码如下:

var values = [['zhao', 1],['qian', 2],['sun', 3]
]var sql = 'insert into test_name(name, id) values ? on duplicate key update name = values(name)';
connection.query(sql, [values], (err, results, fields) => {if (err) { console.log('UPDATE ERROR - ', err.message);throw err}console.log(results)
})connection.end()

这样我们能轻松的在connection.query的回调函数中写执行完所有更新后的操作了,这种方式本质上是当有重复数据的时候先删除了原先记录并保留未更新字段,再进行插入,所以以上代码虽然只更新了3条语句,而affectedrows却有6行:

3,拼接update语句
mysql可以同时执行多条sql语句,如果我们将要执行的所有update语句拼成一条执行,是不是就可以实现批量更新了呢,代码如下:

var mysql = require('mysql')var myCon = require('./config/config.js')var connection = mysql.createConnection({  host: myCon.mysql.host, // 连接的服务器user: myCon.mysql.user, // 用户名password: myCon.mysql.password, // 用户密码database: myCon.mysql.database, // 选择的库multipleStatements: true
})connection.connect() // 创建一个mysql的线程var values = [['tong', 1],['hua', 2],['shun', 3]
]var model_sql = 'update test_name set name = ? where id = ?';var sqls = ''// 拼接sql语句
values.forEach((item, index)=>{sqls += mysql.format(model_sql, item) + ';'
})
/* sqls打印结果:
update test_name set name = 'tong' where id = 1;update test_name set name = 'hua' where id = 2;update test_name set name = 'shun'
where id = 3;
*/
console.log(sqls) connection.query(sqls, (err, results, fields) => {if (err) { console.log('UPDATE ERROR - ', err.message);throw err}console.log(results)
})connection.end()

注意node.js中,mysql默认是不允许一次性同时执行多条sql语句的,如果要同时执行多条sql语句,需要在创建mysql连接的时候,设置multipleStatements为true:

node.js中mysql批量插入更新的三种方法相关推荐

  1. mysql如何防止插入重复数据_防止MySQL重复插入数据的三种方法

    新建表格 CREATE TABLE `person` ( `id` int NOT NULL COMMENT '主键', `name` varchar(64) CHARACTER SET utf8 C ...

  2. mysql 禁止插入重复数据_防止MySQL重复插入数据的三种方法

    新建表格 CREATE TABLE `person` ( `id` int NOT NULL COMMENT '主键', `name` varchar(64) CHARACTER SET utf8 C ...

  3. MySQL批量插入数据的几种方法

    最近公司要求测试数据库的性能,就上网查了一些批量插入数据的代码,发现有好几种不同的用法,插入同样数据的耗时也有区别 别的先不说,先上一段代码与君共享 方法一: package com.bigdata; ...

  4. 数据库批量插入数据的三种方法

    一.准备工作 测试环境:SpringBoot项目+MybatisPlus框架+MySQL数据库+Lombok 二.导入依赖 <dependency><groupId>org.s ...

  5. Mysql批量插入更新性能优化

    Mysql批量插入更新性能优化 对于数据量较大的插入和更新,因io/cpu等性能瓶颈,会产生大量的时间消耗,目前主流的优化主要包括预编译.单条sql插入多条数据.事务插入等,下面详细介绍一下: 单条插 ...

  6. mybatis批量更新数据三种方法效率对比

    探讨批量更新数据三种写法的效率问题. 实现方式有三种, 1> 用for循环通过循环传过来的参数集合,循环出N条sql,需要在db链接url后面带一个参数  &allowMultiQuer ...

  7. mybatis批量更新数据三种方法

    具体的可以参考下面链接: ​​​​​​mybatis批量更新数据三种方法效率对比_PreciousLife的博客-CSDN博客_mybatis 批量更新 此处说明下,若是使用for循环遍历方式,来生成 ...

  8. SQLServer 批量插入数据的两种方法

    SQLServer 批量插入数据的两种方法- 发布:dxy 字体:[增加 减小] 类型:转载 在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用In ...

  9. 【在PowerPoint中插入视频的三种方法】

    为了能更好地帮助大家合理地在PowerPoint课件中插入和播放视频文件, 在PowerPoint中插入视频的三种方法 ,本文特向大家介绍PowerPoint中插入和处理视频的三种方法. 直接播放视频 ...

最新文章

  1. 分布式熔断降级平台aegis
  2. oracle数据库多表嵌套,sql – 在oracle中更新多个嵌套表中的多个记录
  3. 过程的首要目的是好的结果
  4. VS2010上使用Qt 5.2.1出现 “There's no Qt version assigned to this project for platform Win32”错误的解决办法
  5. java.util.concurrent.Exchanger应用范例与原理浅析
  6. 【数据结构与算法】二叉查找树的Java实现
  7. hdoj 4790 Just Random 【数学】
  8. USSD设置呼叫转移功能
  9. 大数据系统体系架构(含图示)
  10. java程序在哪里运行_JAVA代码是怎么运行的
  11. Eureka的自我保护机制
  12. VR技术给我们的生活带来哪些影响
  13. 开发那些坑之使用百川趣拍sd集成真实项目
  14. ON_NOTIFY用法
  15. 浅谈JVM(面试常考)
  16. 三百六十行对比(旧社会)
  17. 【若依(ruoyi)】summernote富文本编辑器的使用
  18. STC单片机 VS/HX1838红外接收和发送实验
  19. sizeof(string)到底是多少?
  20. “十一黄金周” 绵山笑迎五湖四海宾客

热门文章

  1. WaitForSingleObject SetEvent
  2. Java基础算法题(18):两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三
  3. TCP分片和IP分片
  4. java程序员从笨鸟到菜鸟之(二十一)正则表达式
  5. 用DensePose,教照片里的人学跳舞,系群体鬼畜 | ECCV 2018
  6. vivado2018.3创建一个流水灯(基于创龙k7核心开发板)
  7. 单片机c语言程序为什么要加密,(转老贴)单片机加密方法简介:
  8. python中闭包函数_Python的闭包问题(关于内嵌函数引用闭包函数的变量问题)
  9. js template换行_js 实现自动换行
  10. 拼多多发展量子计算机,IBM首次接入三方共建量子生态系统,量子计算或将决定未来的科技走向!...