node+mysql2模块使用

前言

  • 文中仅根据个人理解列出一些常用功能
  • node-mysql2英文原版
  • node-mysql2node-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-mysql2node-mysql的升级版,所有它完全兼容了node-mysql的API
node-mysql英文原版文档
node-mysql中文文档参考


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容

  • JDBC基础知识 一、采用JDBC访问数据库的基本步骤: A.载入JDBC驱动程序 B.定义连接URL ...
    java日记阅读 3,841评论 0 20
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,608评论 18 399
  • 这瞬间的孤独无人会。。。
    媳妇不败家赚钱给谁花阅读 186评论 0 0
  • 如果你遇见17岁的自己,只能说一句话,你会说什么? 在这个安静的时刻,想起了几天前看完的那本刘同的新书,浮现出36...
    原来是雪姑娘阅读 388评论 0 5
  • 地上的叶子那么多,你总拾不完。总有一个季节,树上的叶子会掉,你总抱怨,为什么总是有那么多事情,为什么日子总那么苦。...
    梅茶阅读 346评论 0 2