node+mysql2模块使用
2018-08-21 本文已影响0人
独自迈向前方
前言
- 文中仅根据个人理解列出一些常用功能
- node-mysql2英文原版
-
node-mysql2
与node-mysql
的区别没有详细比对(我个人认为mysql2比较人性化) -
node-mysql2
模块是node-mysql
模块的一个扩展
安装
npm install --save mysql2
快速入门
// 引入
const mysql = require('mysql2');
// 创建数据库连接
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password:'root',
database: 'test',
charset:'utf8',
});
// 简单查询
connection.query(
'SELECT * FROM `table` WHERE `name` = "张三" AND `age` > 45',
function(err, results, fields) {
console.log(results); // results contains rows returned by server
console.log(fields); // fields contains extra meta data about results, if available
}
);
// 使用占位符
connection.query(
'SELECT * FROM `table` WHERE `name` = ? AND `age` > ?',
['张三', 45],
function(err, results) {
console.log(results);
}
);
使用连接池
连接池有助于减少连接到MySQL服务器的时间,通过重用以前的连接
可以避免查询的延迟,减少建立新连接所带来的开销。
const mysql = require('mysql2');
// 创建一个默认配置的连接池
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password:'root',
database: 'test',
charset:'utf8', //应该设置编码(省略在某些情况下会有错误)
//以下选项均为默认值(如果不需要变动可省略)
acquireTimeout:10000, //获取连接的毫秒
waitForConnections: true, /为true时,连接排队等待可用连接。为false将立即抛出错误
connectionLimit: 10, //单次可创建最大连接数
queueLimit: 0 //连接池的最大请求数,从getConnection方法前依次排队。设置为0将没有限制
});
连接池并未初始连接所有连接,当需要操作数据库时需要先进行获取连接对象
获取连接对象的方法(pool.query()
||pool.execute()
||pool.getConnection()
)
注:query()
和execute()
作用一样(自动获取连接释放连接)
// true 表示条件,单个可直接使用如下,多个使用数组格式。例:['name',5]
pool.query("select * from table where ?",true,(err,res)=>{
})
pool.getConnection()
可以获取到连接对象 操作后建议主动的释放连接
pool.getConnection(function(err, conn) {
conn.query(/* ... */);
// 完成后请不要忘记释放连接!(将连接返回到连接池中)
conn.release();
})
事务操作
/**
* 1、使用```pool.getConnection()```获取到连接对象```conn```
* 2、使用```conn.beginTransaction()```声明开始事务操作
* 3、使用```conn.rollback()```进行事务回滚
* 4、使用```conn.commit()```进行事务提交
*/
pool.getConnection((err,conn)=>{
conn.release(); //试验证明 该方法放在此处调用也是可行的
conn.beginTransaction(err=>{
conn.query('update users set pwd=? where id=?',[1212,12],(err,res)=>{
if(err){
// 使用return是防止代码往下运行
return conn.rollback(_=>{
// 回滚后 会执行该回调函数(此处可处理一些后续的额外操作)
});
}
conn.query('select * from users where id=12',(err2,res2)=>{
if(err2){
return conn.rollback();
}
// 执行完所有操作后 进行提交
conn.commit(err3=> {
if(err3) {
return conn.rollback();
}
console.log('success!');
});
})
})
})
})
分块查询
/**
* 通过```conn.pause()```可暂停查询,当大量数据处理时很有用
* 通过```conn.resume()```可继续查询,当处理完一段之后可通过该方法继续IO操作
* @return {[type]} [description]
*/
pool.getConnection((err,conn)=>{
let query = conn.query('select * from users');
query.on('error',err=>{
// 错误处理,在这个事件之后会发送一个'end'事件
})
.on('fields',fields=>{
// 查询行字段信息
})
.on('result',row=>{
// 暂停(row为查询的数据每查询到一行触发一次)
conn.pause();
// 继续查询
conn.resume();
})
.on('fields',fields=>{
// 查询行字段信息(数据格式参考 文末 select(fields) )
})
.on('end',_=>{
conn.release();
// 无论成功与否最后均会触发该事件
})
})
结合分块查询也可以实现转换为其它流的操作
略
关闭连接池
pool.end(function (err) {
});
Promise 用法
以下使用
ES7
语法async/await
演示
async function main() {
const mysql = require('mysql2/promise');
// 创建连接
const conn = await mysql.createConnection({host:'localhost', user: 'root', password:'root', database: 'test'});
// 允许使用Promise第三方库,如下:
// const bluebird = require('bluebird');
// const conn = await mysql.createConnection({host:'localhost', user: 'root', database: 'test', Promise: bluebird});
// 数据库操作
const [rows, fields] = await conn.execute('SELECT * FROM `table` WHERE `name` = ? AND `age` > ?', ['Morty', 14]);
}
连接池的
Promise
用法
async function main() {
const mysql = require('mysql2');
const pool = mysql.createPool({host:'localhost', user: 'root', password:'root' database: 'test'});
const promisePool = pool.promise();
const [rows,fields] = await promisePool.query("SELECT 1");
}
返回数据参考
insert
// 获取ID res[0].insertId
[ ResultSetHeader {
fieldCount: 0,
affectedRows: 1,
insertId: 10,
info: '',
serverStatus: 2,
warningStatus: 0 },
undefined ]
// 插入三行 insertId为第一行的ID
[ ResultSetHeader {
fieldCount: 0,
affectedRows: 3,
insertId: 11,
info: '&Records: 3 Duplicates: 0 Warnings: 0',
serverStatus: 2,
warningStatus: 0 },
undefined ]
update
[ ResultSetHeader {
fieldCount: 0,
affectedRows: 1,
insertId: 0,
info: '(Rows matched: 1 Changed: 1 Warnings: 0',
serverStatus: 2,
warningStatus: 0,
changedRows: 1 },
undefined ]
// 操作三行 变动两行
[ ResultSetHeader {
fieldCount: 0,
affectedRows: 3,
insertId: 0,
info: '(Rows matched: 3 Changed: 2 Warnings: 0',
serverStatus: 2,
warningStatus: 0,
changedRows: 2 },
undefined ]
delete
// 删除失败则 affectedRows 为 0
[ ResultSetHeader {
fieldCount: 0,
affectedRows: 1,
insertId: 0,
info: '',
serverStatus: 2,
warningStatus: 0 },
undefined ] 0
select
// 获取第一行的name res[0][0].name
[
[ TextRow { id: 13, name: '轮回奇缘', pwd: null, age: null } ],
[ TextRow { id: 14, name: '轮回奇缘2', pwd: 11, age: 18 } ],
[ TextRow { id: 15, name: '轮回奇缘3', pwd: 22, age: 18 } ],
]
select (fields)
[ { catalog: 'def',
schema: 'test',
name: 'id',
orgName: 'id',
table: 'users',
orgTable: 'users',
characterSet: 63,
columnLength: 11,
columnType: 3,
flags: 16899,
decimals: 0 },
{ catalog: 'def',
schema: 'test',
name: 'name',
orgName: 'name',
table: 'users',
orgTable: 'users',
characterSet: 33,
columnLength: 150,
columnType: 253,
flags: 0,
decimals: 0 },
{ catalog: 'def',
schema: 'test',
name: 'age',
orgName: 'age',
table: 'users',
orgTable: 'users',
characterSet: 63,
columnLength: 3,
columnType: 1,
flags: 0,
decimals: 0 } ]
因为
node-mysql2
是node-mysql
的升级版,所有它完全兼容了node-mysql
的API
node-mysql英文原版文档
node-mysql中文文档参考