美文网首页
node+mysql2模块使用

node+mysql2模块使用

作者: 独自迈向前方 | 来源:发表于2018-08-21 15:36 被阅读0次

    前言

    • 文中仅根据个人理解列出一些常用功能
    • 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模块使用

          本文链接:https://www.haomeiwen.com/subject/nakjiftx.html