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中文文档参考


你可能感兴趣的:(node+mysql2模块使用)