node.js中对 mysql 进行增删改查等操作和async,await处理
要对mysql进行操作,我们需要安装一个mysql的库。
一、安装mysql库
npm install mysql --save
二、对mysql进行简单查询操作
const mysql = require('mysql');
//创建数据库连接
let conn = mysql.createConnection({
//主机地址
host: '127.0.0.1',
//用户名
user: 'root',
//密码
password: '123456',
//数据库
database: 'test',
//端口
port: 3306,
//字符集
charset: 'utf8'
});
//连接数据库
conn.connect(function (err) {
if (err) {
throw err;
}
console.log('连接成功');
});
//查询数据库
conn.query('select * from tb_user', function (err, data, field) {
if (err) {
throw err;
}
//data表示结果集数据,是一个数组
console.log(data);
data.forEach(function (value) {
console.log(value.id, value.user_name, value.addr);
});
//表字段的详细信息
console.log(field);
});
//关闭数据库连接
conn.end();
二、对mysql进行增删改操作
const mysql = require('mysql');
//创建数据库连接
let conn = mysql.createConnection({
//主机地址
host: '127.0.0.1',
//用户名
user: 'root',
//密码
password: '123456',
//数据库
database: 'test',
//端口
port: 3306,
//字符集
charset: 'utf8'
});
//连接数据库
conn.connect(function (err) {
if (err) {
throw err;
}
console.log('连接成功');
});
//插入数据,query()方法可以对sql语句进行参数绑定,用?号作为占位符。
conn.query('insert into tb_user values(null, ?, ?)', ['xxx', 'xxx'], function (err, data) {
if (err) {
throw err;
}
if (data && data.affectedRows) {
console.log('插入数据成功,id为', data.insertId);
}
});
//修改数据
conn.query('update tb_user set user_name = ? where id = ?', ['ggg', 7], function (err, data) {
if (err) {
throw err;
}
if (data && data.affectedRows) {
console.log('修改数据成功');
}
});
//删除数据
conn.query('delete from tb_user where id = ?', [5], function (err, data) {
if (err) {
throw err;
}
if (data && data.affectedRows) {
console.log('删除数据成功');
}
});
//关闭数据库连接
conn.end();
三、使用mysql连接池来优化对数据库的操作
频繁的连接和断开mysql是比较消耗资源的,我们可以创建一个连接池,复用连接池中的连接,提高效率。
const mysql = require('mysql');
//创建数据库连接池
let pool = mysql.createPool({
//连接数量,默认是10
connectionLimit: 20,
//主机地址
host: '127.0.0.1',
//用户名
user: 'root',
//密码
password: '123456',
//数据库
database: 'test',
//端口
port: 3306,
//字符集
charset: 'utf8'
});
//pool.query()方法可以自动的帮我们在连接池中获取可用连接
pool.query('select * from tb_user', function (err, data) {
if (err) {
throw err;
}
data.forEach(function (value) {
console.log(value.id, value.user_name, value.addr);
});
});
//当然我们也可以手动获取可用连接
pool.getConnection(function (err, conn) {
if (err) {
throw err;
}
conn.query('select * from `order`', function (err, data) {
if (err) {
throw err;
}
data.forEach(function (value) {
console.log(value.id, value.order_id, value.user_id);
});
//连接用完之后,需要释放,重新放回连接池中。
//注意这里并没有销毁该连接,该连接仍然可用,但需要重新获取
conn.release();
});
});
//从连接池中获取连接时,将触发该事件
pool.on('acquire', function (conn) {
console.log('获取连接', conn.threadId);
});
//在连接池中建立新连接时,将触发该事件
pool.on('connection', function (conn) {
console.log('建立新连接', conn.threadId);
});
//等待可用连接时,将触发该事件
pool.on('enqueue', function () {
console.log('等待可用连接');
});
//当连接释放回池中时,触发该事件
pool.on('release', function (conn) {
console.log('连接被释放回池中', conn.threadId);
});
//结束池中所有的连接,不然node.js的事件循环会一直保持
setTimeout(function () {
pool.end(function (err) {
console.log('关闭连接池');
console.log(err);
});
}, 3000);
四、按流的方式进行查询
const mysql = require('mysql');
//创建数据库连接
let conn = mysql.createConnection({
//主机地址
host: '127.0.0.1',
//用户名
user: 'root',
//密码
password: '123456',
//数据库
database: 'test',
//端口
port: 3306,
//字符集
charset: 'utf8'
});
let query = conn.query('select * from tb_user');
//Query类继承自Sequence,而Sequence继承自EventEmitter
//所以Query类的实例是可以监听事件
//发生错误时
query.on('error', function (err) {
console.log(err);
});
//获取查询字段信息
query.on('fields', function (fields) {
console.log(fields);
});
//获取查询结果
query.on('result', function (result) {
//暂停获取结果
conn.pause();
//跟流的pause()和resume()很类似,控制获取数据的频率。
setTimeout(function () {
console.log(result);
//恢复获取结果
conn.resume();
}, 1000);
});
//查询结束
query.on('end', function () {
console.log('查询结束');
});
conn.end();
通过query.stream()方法返回一个可读流来获取数据
const mysql = require('mysql');
//创建数据库连接
let conn = mysql.createConnection({
//主机地址
host: '127.0.0.1',
//用户名
user: 'root',
//密码
password: '123456',
//数据库
database: 'test',
//端口
port: 3306,
//字符集
charset: 'utf8'
});
//从一个查询中获取一个可读流
let qs = conn.query('select * from tb_user').stream({highWaterMark: 2});
let result = [];
qs.on('data', function (data) {
result.push(data);
});
qs.on('end', function () {
console.log('查询结束');
console.log(result);
});
conn.end();
五、mysql的事务处理
const mysql = require('mysql');
//创建数据库连接
let conn = mysql.createConnection({
//主机地址
host: '127.0.0.1',
//用户名
user: 'root',
//密码
password: '123456',
//数据库
database: 'test',
//端口
port: 3306,
//字符集
charset: 'utf8'
});
//连接数据库
conn.connect(function (err) {
if (err) {
throw err;
}
console.log('连接成功');
});
//开启一个事务
conn.beginTransaction(function (err) {
if (err) {
throw err;
}
conn.query('update account set money = money - 50 where name = ?', ['A'], function (err, data) {
if (err) {
//如果有错误则回滚
return conn.rollback(function () {
throw err;
});
}
conn.query('update account set money = money + 50 where name = ?', ['B'], function (err, data) {
if (err) {
//如果有错误则回滚
return conn.rollback(function () {
throw err;
});
}
//提交事务
conn.commit(function (err) {
if (err) {
//如果有错误则回滚
return conn.rollback(function () {
throw err;
});
}
console.log('处理成功');
conn.end();
});
});
});
});
六、解决mysql嵌套回调的问题
有些时候我们的操作需要上一个操作的结果,这样会导致比较深的嵌套问题,为了解决可以使用async和await来解决,而async和await又是基于promise的。
const mysql = require('mysql');
//创建数据库连接
let conn = mysql.createConnection({
//主机地址
host: '127.0.0.1',
//用户名
user: 'root',
//密码
password: '123456',
//数据库
database: 'test',
//端口
port: 3306,
//字符集
charset: 'utf8'
});
function query(conn, sql, params = []) {
if (!conn) {
return;
}
return new Promise(function (resolve, reject) {
conn.query(sql, params, function (err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
(async function () {
let result = await query(conn, 'select * from tb_user');
console.log(result);
let row = await query(conn, 'select * from tb_user where id = ?', [result[0].id]);
console.log(row);
conn.end();
})();
当然我们还可以使用 util.promiseify() 进行包装。
const mysql = require('mysql');
const util = require('util');
//创建数据库连接
let conn = mysql.createConnection({
//主机地址
host: '127.0.0.1',
//用户名
user: 'root',
//密码
password: '123456',
//数据库
database: 'test',
//端口
port: 3306,
//字符集
charset: 'utf8'
});
//注意通过util.promisify进行包装的函数,必须满足
//1、函数的最后一个参数是回调函数
//2、回调函数的参数为(err, result),前者是错误,后者是正常结果
//注意这里不要重新创建一个变量,不然会报错。
conn.query = util.promisify(conn.query);
(async function () {
let result = await conn.query('select * from tb_user');
console.log(result);
let row = await conn.query('select * from tb_user where id = ?', [result[0].id]);
console.log(row);
conn.end();
})();
node.js中对 mysql 进行增删改查等操作和async,await处理的更多相关文章
- MySQL常用增删改查等操作语句
修改数据库的字符集 mysql>use mydb mysql>alter database mydb character set utf8;创建数据库指定数据库的字符集 ...
- js中实现cookie的增删改查(document.cookie的使用详情)
一.设置cookie的值 1.每个cookie都是一个名称/值对,名称/值对用等号连接,并将该名称/值对赋值给document.cookie即可.如:document.cookie="id= ...
- koa+mysql实现增删改查-全栈之路(001)
Date: 2020-4-23 以前很少写文章,从今天开始我要挑战一下自己,连续输出100篇技术类文章.这100篇文章我尽量以实战案例为主. 如果你觉得本文还不错,记得关注或者给个 star,你们的赞 ...
- MVC3.0+knockout.js+Ajax 实现简单的增删改查
MVC3.0+knockout.js+Ajax 实现简单的增删改查 自从到北京入职以来就再也没有接触MVC,很多都已经淡忘了,最近一直在看knockout.js 和webAPI,本来打算采用MVC+k ...
- MySQL之增删改查
前言:以下是MySQL最基本的增删改查语句,很多IT工作者都必须要会的命令,也是IT行业面试最常考的知识点,由于是入门级基础命令,所有所有操作都建立在单表上,未涉及多表操作. 前提:在进行" ...
- Java连接MySQL数据库增删改查通用方法
版权声明:本文为博主原创文章,未经博主允许不得转载. Java连接MySQL数据库增删改查通用方法 运行环境:eclipse+MySQL 以前我们Java连接MySQL数据库都是一个数据库写一个类,类 ...
- MySQL数据库(增删改查语句)
MySQL数据库(增删改查语句)一.登录数据库:----> mysql -uroot -proot;(对应用户名和密码)二.SQL语句: 数据定义语言DDL 用来定义数据库.表.列,关 ...
- python操作mysql数据库增删改查的dbutils实例
python操作mysql数据库增删改查的dbutils实例 # 数据库配置文件 # cat gconf.py #encoding=utf-8 import json # json里面的字典不能用单引 ...
- 在ASP.NET MVC4中实现同页面增删改查,无弹出框02,增删改查界面设计
在上一篇"在ASP.NET MVC4中实现同页面增删改查,无弹出框01,Repository的搭建"中,已经搭建好了Repository层,本篇就剩下增删改查的界面了......今 ...
随机推荐
- 关于Chrome 67 以后版本无法离线安装扩展的解决方法
升级了Chrome,突然发现扩展管理页面有问题—— 无法离线安装扩展,拖拽crx文件至该页面,Chrome竟然一直提示“无法从该网站添加应用,扩展程序和用户脚本”. 如图: 谷歌自Chrome 67版 ...
- 关于对CSS中超链接那部分的设置
a:link{ //正常下的超链接 color:red; //超链接的颜色 text ...
- (Python基础)简单购物车代码
以下是最简单,最基础的购物车代码,一起学习,一起参考.product_list = [ ('Iphone',5800), ('Mac Pro',15800), ('car',580000), ('co ...
- Android开发 集成极光推送中的问题
AndroidManifest.xml清单文件报错: cn.jpush.android.service.DataProvider@exported value=(true)报错,解决如下: 根据报错行 ...
- Splunk 丰富数据方法
方法1: 查找 Step 1.创建CSV文件,首字段为索引字段(关联字段) 2.导入CSV文件,Settings, Lookups, Lookup tables files 3.配置Lookup de ...
- Redis单机版分布式锁实现
转载自:https://www.cnblogs.com/linjiqin/p/8003838.html Redis分布式锁的正确实现方式 前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基 ...
- gp工具的许可
还是要在代码里许可 static class Program { [STAThread] static void Main() { ESRI.ArcGIS.RuntimeManager.Bind(ES ...
- 以time.py为文件名时,调用time包
以time.py为文件名时,调用time包,会报有什么问题呢,思考一下
- 剑指offer——二叉树的镜像
题目:操作给定的二叉树,将其变换为源二叉树的镜像. 思路:前序(根左右的顺序)遍历一棵树,在存储的时候将其左右树进行交换,最后按照处理后的树还原,即得到其镜像. /** public class Tr ...
- [Docker] 容器开发环境最佳实践理论
保持 image 小 选择合适的 base image. 使用 multi-stage 构建. https://docs.docker.com/develop/develo ...