zoukankan      html  css  js  c++  java
  • nodejs中mysql用法

    nodejs也算是一篇脚本了我们来看nodejs如何使用mysql数据库了有了它们两组合感觉还是非常的不错哦,下面一起来看nodejs中使用mysql数据库的示例,希望能够帮助到各位。
    <script>ec(2);</script>


    db-mysql因为 node-waf: not found 已经不能使用,可以使用mysql代替.

    本文主要是[node-mysql]: https://www.npmjs.com/package/node-mysql 的翻译,也去除了一部分自己暂时没有使用到的,如集群.

    安装

    npm install mysql
    简介

    纯JavaScript编写,使用的MIT协议.

    var mysql      = require('mysql');
    var connection = mysql.createConnection({
      host     : 'localhost',
      user     : 'me',
      password : 'secret',
      database : 'my_db'
    });

    connection.connect();

    // 顺序执行
    connection.query('SELECT 1 1 AS solution', function(err, rows, fields) {
      if (err) throw err;

      console.log('The solution is: ', rows[0].solution);
    });

    // 关闭数据库连接
    connection.end();
    建立数据库连接

    官方推荐如下方式建立数据库连接

    var mysql      = require('mysql');
    var connection = mysql.createConnection({
      host     : 'example.org',
      user     : 'bob',
      password : 'secret'
    });

    connection.connect(function(err) {
      if (err) {
        console.error('error connecting: ' err.stack);
        return;
      }

      console.log('connected as id ' connection.threadId);
    });
    也可以直接通过查询建立连接

    var mysql      = require('mysql');
    var connection = mysql.createConnection(...);

    connection.query('SELECT 1', function(err, rows) {
      // connected! (unless `err` is set)
    });
    连接的选项

    host : The hostname of the database you are connecting to. (Default: 
    localhost )
    port : The port number to connect to. (Default: 3306 )
    localAddress : The source IP address to use for TCP connection. (Optional)
    socketPath : The path to a unix domain socket to connect to. When used host 
    and port are ignored.
    user : The MySQL user to authenticate as.
    password : The password of that MySQL user.
    database : Name of the database to use for this connection (Optional).
    charset : The charset for the connection. This is called "collation" in the SQL-level 
    of MySQL (like utf8_general_ci ). If a SQL-level charset is specified (like utf8mb4 ) 
    then the default collation for that charset is used. (Default: 'UTF8_GENERAL_CI' )
    timezone : The timezone used to store local dates. (Default: 'local' )
    connectTimeout : The milliseconds before a timeout occurs during the initial connection 
    to the MySQL server. (Default: 10000 )
    stringifyObjects : Stringify objects instead of converting to values. See 
    issue #501 . (Default: 'false' )
    insecureAuth : Allow connecting to MySQL instances that ask for the old 
    (insecure) authentication method. (Default: false )
    typeCast : Determines if column values should be converted to native 
    JavaScript types. (Default: true )
    queryFormat : A custom query format function. See.
    supportBigNumbers : When dealing with big numbers (BIGINT and DECIMAL columns) in the database, 
    you should enable this option (Default: false ).
    bigNumberStrings : Enabling both supportBigNumbers and bigNumberStrings forces big numbers 
    (BIGINT and DECIMAL columns) to be always returned as JavaScript String objects (Default: false ). 
    Enabling supportBigNumbers but leaving bigNumberStrings disabled will return big numbers as String 
    objects only when they cannot be accurately represented with [JavaScript Number objects] ( http://ecma262-5.com/ELS5_HTML.htm#Section_8.5 ) 
    (which happens when they exceed the [-2^53, 2^53] range), otherwise they will be returned as 
    Number objects. This option is ignored if supportBigNumbers is disabled.
    dateStrings : Force date types (TIMESTAMP, DATETIME, DATE) to be returned as strings rather then 
    inflated into JavaScript Date objects. (Default: false )
    debug : Prints protocol details to stdout. (Default: false )
    trace : Generates stack traces on Error to include call site of library 
    entrance ("long stack traces"). Slight performance penalty for most calls. 
    (Default: true )
    multipleStatements : Allow multiple mysql statements per query. Be careful 
    with this, it could increase the scope of SQL injection attacks. (Default: false )
    flags : List of connection flags to use other than the default ones. It is 
    also possible to blacklist default ones. For more information, check 
    .
    ssl : object with ssl parameters or a string containing name of ssl profile. See.
    下面这样通过字符串方式也可以:

    var connection = mysql.createConnection('mysql://user:pass@host/db?debug=true&charset=BIG5_CHINESE_CI&timezone=-0700');
    关闭连接

    有两种方式关闭连接:end和destroy

    使用end回调关闭会更优雅一些,他会确保已经在队列中的查询会发送一个 COM_QUIT 给mysql.

    connection.end(function(err) {
      // The connection is terminated now
    });
    使用destroy会直接粗暴关闭连接,不会触发connection的任何回调函数.

    connection.destroy();
    使用连接池

    var mysql = require('mysql');
    var pool  = mysql.createPool({
      connectionLimit : 10,
      host            : 'example.org',
      user            : 'bob',
      password        : 'secret',
      database        : 'my_db'
    });

    pool.query('SELECT 1 1 AS solution', function(err, rows, fields) {
      if (err) throw err;

      console.log('The solution is: ', rows[0].solution);
    });
    通过 connection.release() 释放连接

    var mysql = require('mysql');
    var pool  = mysql.createPool(...);

    pool.getConnection(function(err, connection) {
      // Use the connection
      connection.query( 'SELECT something FROM sometable', function(err, rows) {
        // And done with the connection.
        // 释放连接
        connection.release();

        // Don't use the connection here, it has been returned to the pool.
      });
    });
    如果你想从连接池挂壁一个连接,使用 connection.destroy() .当然如果有需要连接池会新建一个代替.

    连接池对于连接时懒加载的.比如你配置了100个连接,而现在只使用了5个,那只会初始化5个.

    连接池回收一个连接,后会往mysql服务器发送一个ping,确认连接是否有效.

    连接池的选项

    连接池可以直接使用连接的选项,然后在新建连接时,直接用这些配置新建连接.连接池添加了下面的选项:

    acquireTimeout : The milliseconds before a timeout occurs during the connection
    acquisition. This is slightly different from connectTimeout , because acquiring 
    a pool connection does not always involve making a connection. (Default: 10000 )
    waitForConnections : Determines the pool's action when no connections are 
    available and the limit has been reached. If true , the pool will queue the 
    connection request and call it when one becomes available. If false , the 
    pool will immediately call back with an error. (Default: true )
    connectionLimit : The maximum number of connections to create at once. 
    (Default: 10 )
    queueLimit : The maximum number of connection requests the pool will queue 
    before returning an error from getConnection . If set to 0 , there is no 
    limit to the number of queued connection requests. (Default: 0 )
    连接池事件

    建立连接会触发 connection .

    pool.on('connection', function (connection) {
      connection.query('SET SESSION auto_increment_increment=1')
    });
    当有回调排队等待连接时,触发 enqueue

    pool.on('enqueue', function () {
      console.log('Waiting for available connection slot');
    });
    关闭连接池

    之前提到关闭连接池中的连接后,当需要使用时连接池会自动新建,所以使用 connection.end() 或 connection.destroy() 时无法关闭连接池的,需要使用 pool.end() :

    pool.end(function (err) {
      // all connections in the pool have ended
    });
    查询语句

    在 Connection 或 Pool 实例上使用 .query() 是最简单的查询.

    第一种方式是直接拼接好查询用的sql .query(sqlString, callback)

    connection.query('SELECT * FROM `books` WHERE `author` = "David"', function (error, results, fields) {
      // error will be an Error if one occurred during the query
      // results will contain the results of the query
      // fields will contain information about the returned results fields (if any)
    });
    或者使用占位符,然后传参 .query(sqlString, values, callback)

    connection.query('SELECT * FROM `books` WHERE `author` = ?', ['David'], function (error, results, fields) {
      // error will be an Error if one occurred during the query
      // results will contain the results of the query
      // fields will contain information about the returned results fields (if any)
    });
    第三种方式是使用options. .query(options, callback)

    connection.query({
      sql: 'SELECT * FROM `books` WHERE `author` = ?',
      timeout: 40000, // 40s
      values: ['David']
    }, function (error, results, fields) {
      // error will be an Error if one occurred during the query
      // results will contain the results of the query
      // fields will contain information about the returned results fields (if any)
    });
    第二种和第三种使用方式可以混合使用

    connection.query({
        sql: 'SELECT * FROM `books` WHERE `author` = ?',
        timeout: 40000, // 40s
      },
      ['David'],
      function (error, results, fields) {
        // error will be an Error if one occurred during the query
        // results will contain the results of the query
        // fields will contain information about the returned results fields (if any)
      }
    );
    查询参数转义 Escaping query values

    为了避免sql注入攻击,在sql查询使用前,我们需要转义用户提供的任何数据. 使用 mysql.escape() , connection.escape() 或 pool.escape() 方法:

    var userId = 'some user provided value';
    var sql    = 'SELECT * FROM users WHERE id = ' connection.escape(userId);
    connection.query(sql, function(err, results) {
      // ...
    });
    使用占位符 ? ,也行.

    connection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) {
      // ...
    });
    占位符是按顺序替换的.

    connection.query('UPDATE users SET foo = ?, bar = ?, baz = ? WHERE id = ?', ['a', 'b', 'c', userId], function(err, results) {
      // ...
    });
    不同类型的参数,转义规则是不一样的:

    Numbers are left untouched
    Booleans are converted to true / false
    Date objects are converted to 'YYYY-mm-dd HH:ii:ss' strings
    Buffers are converted to hex strings, e.g. X'0fa5'
    Strings are safely escaped
    Arrays are turned into list, e.g. ['a', 'b'] turns into 'a', 'b'
    Nested arrays are turned into grouped lists (for bulk inserts), e.g. [['a', 'b'], ['c', 'd']] turns into ('a', 'b'), ('c', 'd')
    Objects are turned into key = 'val' pairs for each enumerable property on the object. If the property's value is a function, it is skipped; if the 
    property's value is an object, toString() is called on it and the returned value is used.
    undefined / null are converted to NULL
    NaN / Infinity are left as-is. MySQL does not support these, and trying to insert them as values will trigger MySQL errors until they implement 
    support.
    转义还提供对象方式传参数

    var post  = {id: 1, title: 'Hello MySQL'};
    var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
      // Neat!
    });
    console.log(query.sql); // INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'
    不嫌麻烦的话,咱们也可以自己手动转义:

    var query = "SELECT * FROM posts WHERE title=" mysql.escape("Hello MySQL");

    console.log(query); // SELECT * FROM posts WHERE title='Hello MySQL'
    转义查询的关键词 Escaping query identifiers

    如果你对用户提供的关键词没把我 (database / table / column name) ,可以使用 mysql.escapeId(identifier) ,

    connection.escapeId(identifier) or pool.escapeId(identifier) 转义:

    var sorter = 'date';
    var sql    = 'SELECT * FROM posts ORDER BY ' connection.escapeId(sorter);
    connection.query(sql, function(err, results) {
      // ...
    });
    var sorter = 'date';
    var sql    = 'SELECT * FROM posts ORDER BY ' connection.escapeId('posts.' sorter);
    connection.query(sql, function(err, results) {
      // ...
    });
    还可以使用 ?? 做占位符:

    var userId = 1;
    var columns = ['username', 'email'];
    var query = connection.query('SELECT ?? FROM ?? WHERE id = ?', [columns, 'users', userId], function(err, results) {
      // ...
    });

    console.log(query.sql); // SELECT `username`, `email` FROM `users` WHERE id = 1
    Please note that this last character sequence is experimental and syntax might change

    When you pass an Object to .escape() or .query() , .escapeId() is used to avoid SQL injection in object keys.

    准备查询语句Preparing Queries

    You can use mysql.format to prepare a query with multiple insertion points, utilizing the proper escaping for ids and values. A simple example of this follows:

    我们可以使用 mysql.format 来准备一个插入语句,解决转义问题.

    var sql = "SELECT * FROM ?? WHERE ?? = ?";
    var inserts = ['users', 'id', userId];
    sql = mysql.format(sql, inserts);
    这样我们就可以得到一个安全有效,转义好的查询语句. mysql.format 是 SqlString.format 暴露的,所以可以传入stringifyObject和timezone来自定义对象如何转为字符串.

    自定义格式 Custom format

    如果我们想使用其他方式来转义查询语句,可以使用connection的配置.可以使用内置的 .escape() 或其他配置函数.

    connection.config.queryFormat = function (query, values) {
      if (!values) return query;
      return query.replace(/:(w )/g, function (txt, key) {
        if (values.hasOwnProperty(key)) {
          return this.escape(values[key]);
        }
        return txt;
      }.bind(this));
    };

    connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" });
    获取插入行的id

    如果是id自增长方式插入数据,你可以这样获取id:

    connection.query('INSERT INTO posts SET ?', {title: 'test'}, function(err, result) {
      if (err) throw err;

      console.log(result.insertId);
    });
    When dealing with big numbers (above JavaScript Number precision limit), you should consider enabling supportBigNumbers option to be able to read the insert id as a string, otherwise it will throw an error.

    This option is also required when fetching big numbers from the database, otherwise you will get values rounded to hundreds or thousands due to the precision limit.

    获取影响的行数

    我们可以获取影响(新建,修改,删除)涉及的行数

    connection.query('DELETE FROM posts WHERE title = "wrong"', function (err, result) {
      if (err) throw err;

      console.log('deleted ' result.affectedRows ' rows');
    })
    获取修改的行数 Getting the number of changed rows

    我们可以获取update语句修改涉及的行数/

    "changedRows" 不同于 "affectedRows" 不统计符合条件但没有改变值的记录. in that it does not count updated rows whose values were not changed.

    connection.query('UPDATE posts SET ...', function (err, result) {
      if (err) throw err;

      console.log('changed ' result.changedRows ' rows');
    })
    获取连接id

    connection.connect(function(err) {
      if (err) throw err;
      console.log('connected as id ' connection.threadId);
    });
    并行执行查询

    mysql是顺序执行的,所以我们需要使用多个连接来并行查询.最简答的最法是每个http请求分配一个连接.

    流查询 Streaming query rows

    如果需要查询大量数据并处理每行,可以这样做:

    Sometimes you may want to select large quantities of rows and process each of them as they are received. This can be done like this:

    var query = connection.query('SELECT * FROM posts');
    query
      .on('error', function(err) {
        // Handle error, an 'end' event will be emitted after this as well
      })
      .on('fields', function(fields) {
        // the field packets for the rows to follow
      })
      .on('result', function(row) {
        // Pausing the connnection is useful if your processing involves I/O
        connection.pause();

        processRow(row, function() {
          connection.resume();
        });
      })
      .on('end', function() {
        // all rows have been received
      });
    Please note a few things about the example above:

    Usually you will want to receive a certain amount of rows before starting to 
    throttle the connection using pause() . This number will depend on the 
    amount and size of your rows.
    pause() / resume() operate on the underlying socket and parser. You are 
    guaranteed that no more 'result' events will fire after calling pause() .
    You MUST NOT provide a callback to the query() method when streaming rows.
    The 'result' event will fire for both rows as well as OK packets 
    confirming the success of a INSERT/UPDATE query.
    It is very important not to leave the result paused too long, or you may 
    encounter Error: Connection lost: The server closed the connection. 
    The time limit for this is determined by the 
    net_write_timeout setting 
    on your MySQL server.
    Additionally you may be interested to know that it is currently not possible to

    stream individual row columns, they will always be buffered up entirely. If you

    have a good use case for streaming large fields to and from MySQL, I'd love to

    get your thoughts and contributions on this.

    Piping results with Streams2

    The query object provides a convenience method .stream([options]) that wraps

    query events into a Readable

    Streams2 object. This

    stream can easily be piped downstream and provides automatic pause/resume,

    based on downstream congestion and the optional highWaterMark . The

    objectMode parameter of the stream is set to true and cannot be changed

    (if you need a byte stream, you will need to use a transform stream, like

    objstream for example).

    For example, piping query results into another stream (with a max buffer of 5

    objects) is simply:

    connection.query('SELECT * FROM posts')
      .stream({highWaterMark: 5})
      .pipe(...);
    多语句查询 Multiple statement queries

    由于sql注入的安全问题,多语句查询默认禁用.需要手动启用 {multipleStatements: true} .

    var connection = mysql.createConnection({multipleStatements: true});
    之后就跟普通使用是一样的.

    connection.query('SELECT 1; SELECT 2', function(err, results) {
      if (err) throw err;

      // `results` is an array with one element for every statement in the query:
      console.log(results[0]); // [{1: 1}]
      console.log(results[1]); // [{2: 2}]
    });
    Additionally you can also stream the results of multiple statement queries:

    var query = connection.query('SELECT 1; SELECT 2');

    query
      .on('fields', function(fields, index) {
        // the fields for the result rows that follow
      })
      .on('result', function(row, index) {
        // index refers to the statement this result belongs to (starts at 0)
      });
    If one of the statements in your query causes an error, the resulting Error

    object contains a err.index property which tells you which statement caused

    it. MySQL will also stop executing any remaining statements when an error

    occurs.

    Please note that the interface for streaming multiple statement queries is

    experimental and I am looking forward to feedback on it.

    存储过程 Stored procedures

    跟普通语句一样使用存储过程就好.如果存储过程返回了多个集合的数据,会像多语句查询那样返回结果集.

    join语句时相同列名处理 Joins with overlapping column names

    执行join语句时,很可能会收到重复的列名.

    By default, node-mysql will overwrite colliding column names in the

    order the columns are received from MySQL, causing some of the received values

    to be unavailable.

    However, you can also specify that you want your columns to be nested below

    the table name like this:

    var options = {sql: '...', nestTables: true};
    connection.query(options, function(err, results) {
      /* results will be an array like this now:
      [{
        table1: {
          fieldA: '...',
          fieldB: '...',
        },
        table2: {
          fieldA: '...',
          fieldB: '...',
        },
      }, ...]
      */
    });
    Or use a string separator to have your results merged.

    var options = {sql: '...', nestTables: '_'};
    connection.query(options, function(err, results) {
      /* results will be an array like this now:
      [{
        table1_fieldA: '...',
        table1_fieldB: '...',
        table2_fieldA: '...',
        table2_fieldB: '...',
      }, ...]
      */
    });
    事务 Transactions

    在connection中提供事务

    connection.beginTransaction(function(err) {
      if (err) { throw err; }
      connection.query('INSERT INTO posts SET title=?', title, function(err, result) {
        if (err) {
          return connection.rollback(function() {
            throw err;
          });
        }

        var log = 'Post ' result.insertId ' added';

        connection.query('INSERT INTO log SET data=?', log, function(err, result) {
          if (err) {
            return connection.rollback(function() {
              throw err;
            });
          }  
          connection.commit(function(err) {
            if (err) {
              return connection.rollback(function() {
                throw err;
              });
            }
            console.log('success!');
          });
        });
      });
    });
    beginTransaction(), commit() 和 rollback()只是简单执行START TRANSACTION, COMMIT, 和 ROLLBACK命令.而mysql中很多语句是可以自动提交的.自己翻 MySQL documentation

    Ping

    ping一下,确认连接是否有效,连接池也用.

    A ping packet can be sent over a connection using the connection.ping method. This

    method will send a ping packet to the server and when the server responds, the callback

    will fire. If an error occurred, the callback will fire with an error argument.

    connection.ping(function (err) {
      if (err) throw err;
      console.log('Server responded to ping');
    })
    Timeouts

    Every operation takes an optional inactivity timeout option. This allows you to

    specify appropriate timeouts for operations. It is important to note that these

    timeouts are not part of the MySQL protocol, and rather timeout operations through

    the client. This means that when a timeout is reached, the connection it occurred

    on will be destroyed and no further operations can be performed.

    // Kill query after 60s
    connection.query({sql: 'SELECT COUNT(*) AS count FROM big_table', timeout: 60000}, function (err, rows) {
      if (err && err.code === 'PROTOCOL_SEQUENCE_TIMEOUT') {
        throw new Error('too long to count table rows!');
      }

      if (err) {
        throw err;
      }

      console.log(rows[0].count ' rows');
    });
    Error handling

    This module comes with a consistent approach to error handling that you should

    review carefully in order to write solid applications.

    Most errors created by this module are instances of the JavaScript Error

    object. Additionally they typically come with two extra properties:

    err.code : Either a MySQL server error (e.g. 
    'ER_ACCESS_DENIED_ERROR' ), a Node.js error (e.g. 'ECONNREFUSED' ) or an 
    internal error (e.g. 'PROTOCOL_CONNECTION_LOST' ).
    err.fatal : Boolean, indicating if this error is terminal to the connection 
    object. If the error is not from a MySQL protocol operation, this properly 
    will not be defined.
    Fatal errors are propagated to all pending callbacks. In the example below, a

    fatal error is triggered by trying to connect to an invalid port. Therefore the

    error object is propagated to both pending callbacks:

    var connection = require('mysql').createConnection({
      port: 84943, // WRONG PORT
    });

    connection.connect(function(err) {
      console.log(err.code); // 'ECONNREFUSED'
      console.log(err.fatal); // true
    });

    connection.query('SELECT 1', function(err) {
      console.log(err.code); // 'ECONNREFUSED'
      console.log(err.fatal); // true
    });
    Normal errors however are only delegated to the callback they belong to. So in

    the example below, only the first callback receives an error, the second query

    works as expected:

    connection.query('USE name_of_db_that_does_not_exist', function(err, rows) {
      console.log(err.code); // 'ER_BAD_DB_ERROR'
    });

    connection.query('SELECT 1', function(err, rows) {
      console.log(err); // null
      console.log(rows.length); // 1
    });
    Last but not least: If a fatal errors occurs and there are no pending

    callbacks, or a normal error occurs which has no callback belonging to it, the

    error is emitted as an 'error' event on the connection object. This is

    demonstrated in the example below:

    connection.on('error', function(err) {
      console.log(err.code); // 'ER_BAD_DB_ERROR'
    });

    connection.query('USE name_of_db_that_does_not_exist');
    Note: 'error' events are special in node. If they occur without an attached

    listener, a stack trace is printed and your process is killed.

    tl;dr:This module does not want you to deal with silent failures. You

    should always provide callbacks to your method calls. If you want to ignore

    this advice and suppress unhandled errors, you can do this:

    // I am Chuck Norris:
    connection.on('error', function() {});
    Exception Safety

    This module is exception safe. That means you can continue to use it, even if

    one of your callback functions throws an error which you're catching using

    'uncaughtException' or a domain.

    Type casting

    For your convenience, this driver will cast mysql types into native JavaScript

    types by default. The following mappings exist:

    Number

    TINYINT
    SMALLINT
    INT
    MEDIUMINT
    YEAR
    FLOAT
    DOUBLE
    Date

    TIMESTAMP
    DATE
    DATETIME
    Buffer

    TINYBLOB
    MEDIUMBLOB
    LONGBLOB
    BLOB
    BINARY
    VARBINARY
    BIT (last byte will be filled with 0 bits as necessary)
    String

    Notetext in the binary character set is returned as Buffer , rather

    than a string.

    CHAR
    VARCHAR
    TINYTEXT
    MEDIUMTEXT
    LONGTEXT
    TEXT
    ENUM
    SET
    DECIMAL (may exceed float precision)
    BIGINT (may exceed float precision)
    TIME (could be mapped to Date, but what date would be set?)
    GEOMETRY (never used those, get in touch if you do)
    It is not recommended (and may go away / change in the future) to disable type

    casting, but you can currently do so on either the connection:

    var connection = require('mysql').createConnection({typeCast: false});
    Or on the query level:

    var options = {sql: '...', typeCast: false};
    var query = connection.query(options, function(err, results) {

    });
    You can also pass a function and handle type casting yourself. You're given some

    column information like database, table and name and also type and length. If you

    just want to apply a custom type casting to a specific type you can do it and then

    fallback to the default. Here's an example of converting TINYINT(1) to boolean:

    connection.query({
      sql: '...',
      typeCast: function (field, next) {
        if (field.type == 'TINY' && field.length == 1) {
          return (field.string() == '1'); // 1 = true, 0 = false
        }
        return next();
      }
    });
    WARNING: YOU MUST INVOKE the parser using one of these three field functions in your custom typeCast callback. They can only be called once. (see #539 for discussion)

    field.string()
    field.buffer()
    field.geometry()
    are aliases for

    parser.parseLengthCodedString()
    parser.parseLengthCodedBuffer()
    parser.parseGeometryValue()
    You can find which field function you need to use by looking at: RowDataPacket.prototype._typeCast

    Connection Flags

    If, for any reason, you would like to change the default connection flags, you

    can use the connection option flags . Pass a string with a comma separated list

    of items to add to the default flags. If you don't want a default flag to be used

    prepend the flag with a minus sign. To add a flag that is not in the default list,

    just write the flag name, or prefix it with a plus (case insensitive).

    Please note that some available flags that are not supported (e.g.: Compression), 
    are still not allowed to be specified.

    Example

    The next example blacklists FOUND_ROWS flag from default connection flags.

    var connection = mysql.createConnection("mysql://localhost/test?flags=-FOUND_ROWS");
    Default Flags

    The following flags are sent by default on a new connection:

    CONNECT_WITH_DB - Ability to specify the database on connection.
    FOUND_ROWS - Send the found rows instead of the affected rows as affectedRows .
    IGNORE_SIGPIPE - Old; no effect.
    IGNORE_SPACE - Let the parser ignore spaces before the ( in queries.
    LOCAL_FILES - Can use LOAD DATA LOCAL .
    LONG_FLAG
    LONG_PASSWORD - Use the improved version of Old Password Authentication.
    MULTI_RESULTS - Can handle multiple resultsets for COM_QUERY.
    ODBC Old; no effect.
    PROTOCOL_41 - Uses the 4.1 protocol.
    PS_MULTI_RESULTS - Can handle multiple resultsets for COM_STMT_EXECUTE.
    RESERVED - Old flag for the 4.1 protocol.
    SECURE_CONNECTION - Support native 4.1 authentication.
    TRANSACTIONS - Asks for the transaction status flags.
    In addition, the following flag will be sent if the option multipleStatements 
    is set to true :

    MULTI_STATEMENTS - The client may send multiple statement per query or

    statement prepare.

    Other Available Flags

    There are other flags available. They may or may not function, but are still

    available to specify.

    COMPRESS
    INTERACTIVE
    NO_SCHEMA
    PLUGIN_AUTH
    REMEMBER_OPTIONS
    SSL
    SSL_VERIFY_SERVER_CERT
    Debugging and reporting problems

    If you are running into problems, one thing that may help is enabling the

    debug mode for the connection:

    var connection = mysql.createConnection({debug: true});
    This will print all incoming and outgoing packets on stdout. You can also restrict debugging to

    packet types by passing an array of types to debug:

    var connection = mysql.createConnection({debug: ['ComQueryPacket', 'RowDataPacket']});
    to restrict debugging to the query and data packets.

    If that does not help, feel free to open a GitHub issue. A good GitHub issue

    will have:

    The minimal amount of code required to reproduce the problem (if possible)
    As much debugging output and information about your environment (mysql 
    version, node version, os, etc.) as you can gather.
    Running tests

    The test suite is split into two parts: unit tests and integration tests.

    The unit tests run on any machine while the integration tests require a

    MySQL server instance to be setup.

    Running unit tests

    $ FILTER=unit npm test
    Running integration tests

    Set the environment variables MYSQL_DATABASE , MYSQL_HOST , MYSQL_PORT ,

    MYSQL_USER and MYSQL_PASSWORD . MYSQL_SOCKET can also be used in place

    of MYSQL_HOST and MYSQL_PORT to connect over a UNIX socket. Then run

    npm test .

    For example, if you have an installation of mysql running on localhost:3306

    and no password set for the root user, run:

    $ mysql -u root -e "CREATE DATABASE IF NOT EXISTS node_mysql_test"
    $ MYSQL_HOST=localhost MYSQL_PORT=3306 MYSQL_DATABASE=node_mysql_test MYSQL_USER=root MYSQL_PASSWORD= FILTER=integration npm test

     

    nodejs也算是一篇脚本了我们来看nodejs如何使用mysql数据库了有了它们两组合感觉还是非常的不错哦,下面一起来看nodejs中使用mysql数据库的示例,希望能够帮助到各位。
    <script>ec(2);</script>


    db-mysql因为 node-waf: not found 已经不能使用,可以使用mysql代替.

    本文主要是[node-mysql]: https://www.npmjs.com/package/node-mysql 的翻译,也去除了一部分自己暂时没有使用到的,如集群.

    安装

    npm install mysql
    简介

    纯JavaScript编写,使用的MIT协议.

    var mysql      = require('mysql');
    var connection = mysql.createConnection({
      host     : 'localhost',
      user     : 'me',
      password : 'secret',
      database : 'my_db'
    });

    connection.connect();

    // 顺序执行
    connection.query('SELECT 1 1 AS solution', function(err, rows, fields) {
      if (err) throw err;

      console.log('The solution is: ', rows[0].solution);
    });

    // 关闭数据库连接
    connection.end();
    建立数据库连接

    官方推荐如下方式建立数据库连接

    var mysql      = require('mysql');
    var connection = mysql.createConnection({
      host     : 'example.org',
      user     : 'bob',
      password : 'secret'
    });

    connection.connect(function(err) {
      if (err) {
        console.error('error connecting: ' err.stack);
        return;
      }

      console.log('connected as id ' connection.threadId);
    });
    也可以直接通过查询建立连接

    var mysql      = require('mysql');
    var connection = mysql.createConnection(...);

    connection.query('SELECT 1', function(err, rows) {
      // connected! (unless `err` is set)
    });
    连接的选项

    host : The hostname of the database you are connecting to. (Default: 
    localhost )
    port : The port number to connect to. (Default: 3306 )
    localAddress : The source IP address to use for TCP connection. (Optional)
    socketPath : The path to a unix domain socket to connect to. When used host 
    and port are ignored.
    user : The MySQL user to authenticate as.
    password : The password of that MySQL user.
    database : Name of the database to use for this connection (Optional).
    charset : The charset for the connection. This is called "collation" in the SQL-level 
    of MySQL (like utf8_general_ci ). If a SQL-level charset is specified (like utf8mb4 ) 
    then the default collation for that charset is used. (Default: 'UTF8_GENERAL_CI' )
    timezone : The timezone used to store local dates. (Default: 'local' )
    connectTimeout : The milliseconds before a timeout occurs during the initial connection 
    to the MySQL server. (Default: 10000 )
    stringifyObjects : Stringify objects instead of converting to values. See 
    issue #501 . (Default: 'false' )
    insecureAuth : Allow connecting to MySQL instances that ask for the old 
    (insecure) authentication method. (Default: false )
    typeCast : Determines if column values should be converted to native 
    JavaScript types. (Default: true )
    queryFormat : A custom query format function. See.
    supportBigNumbers : When dealing with big numbers (BIGINT and DECIMAL columns) in the database, 
    you should enable this option (Default: false ).
    bigNumberStrings : Enabling both supportBigNumbers and bigNumberStrings forces big numbers 
    (BIGINT and DECIMAL columns) to be always returned as JavaScript String objects (Default: false ). 
    Enabling supportBigNumbers but leaving bigNumberStrings disabled will return big numbers as String 
    objects only when they cannot be accurately represented with [JavaScript Number objects] ( http://ecma262-5.com/ELS5_HTML.htm#Section_8.5 ) 
    (which happens when they exceed the [-2^53, 2^53] range), otherwise they will be returned as 
    Number objects. This option is ignored if supportBigNumbers is disabled.
    dateStrings : Force date types (TIMESTAMP, DATETIME, DATE) to be returned as strings rather then 
    inflated into JavaScript Date objects. (Default: false )
    debug : Prints protocol details to stdout. (Default: false )
    trace : Generates stack traces on Error to include call site of library 
    entrance ("long stack traces"). Slight performance penalty for most calls. 
    (Default: true )
    multipleStatements : Allow multiple mysql statements per query. Be careful 
    with this, it could increase the scope of SQL injection attacks. (Default: false )
    flags : List of connection flags to use other than the default ones. It is 
    also possible to blacklist default ones. For more information, check 
    .
    ssl : object with ssl parameters or a string containing name of ssl profile. See.
    下面这样通过字符串方式也可以:

    var connection = mysql.createConnection('mysql://user:pass@host/db?debug=true&charset=BIG5_CHINESE_CI&timezone=-0700');
    关闭连接

    有两种方式关闭连接:end和destroy

    使用end回调关闭会更优雅一些,他会确保已经在队列中的查询会发送一个 COM_QUIT 给mysql.

    connection.end(function(err) {
      // The connection is terminated now
    });
    使用destroy会直接粗暴关闭连接,不会触发connection的任何回调函数.

    connection.destroy();
    使用连接池

    var mysql = require('mysql');
    var pool  = mysql.createPool({
      connectionLimit : 10,
      host            : 'example.org',
      user            : 'bob',
      password        : 'secret',
      database        : 'my_db'
    });

    pool.query('SELECT 1 1 AS solution', function(err, rows, fields) {
      if (err) throw err;

      console.log('The solution is: ', rows[0].solution);
    });
    通过 connection.release() 释放连接

    var mysql = require('mysql');
    var pool  = mysql.createPool(...);

    pool.getConnection(function(err, connection) {
      // Use the connection
      connection.query( 'SELECT something FROM sometable', function(err, rows) {
        // And done with the connection.
        // 释放连接
        connection.release();

        // Don't use the connection here, it has been returned to the pool.
      });
    });
    如果你想从连接池挂壁一个连接,使用 connection.destroy() .当然如果有需要连接池会新建一个代替.

    连接池对于连接时懒加载的.比如你配置了100个连接,而现在只使用了5个,那只会初始化5个.

    连接池回收一个连接,后会往mysql服务器发送一个ping,确认连接是否有效.

    连接池的选项

    连接池可以直接使用连接的选项,然后在新建连接时,直接用这些配置新建连接.连接池添加了下面的选项:

    acquireTimeout : The milliseconds before a timeout occurs during the connection
    acquisition. This is slightly different from connectTimeout , because acquiring 
    a pool connection does not always involve making a connection. (Default: 10000 )
    waitForConnections : Determines the pool's action when no connections are 
    available and the limit has been reached. If true , the pool will queue the 
    connection request and call it when one becomes available. If false , the 
    pool will immediately call back with an error. (Default: true )
    connectionLimit : The maximum number of connections to create at once. 
    (Default: 10 )
    queueLimit : The maximum number of connection requests the pool will queue 
    before returning an error from getConnection . If set to 0 , there is no 
    limit to the number of queued connection requests. (Default: 0 )
    连接池事件

    建立连接会触发 connection .

    pool.on('connection', function (connection) {
      connection.query('SET SESSION auto_increment_increment=1')
    });
    当有回调排队等待连接时,触发 enqueue

    pool.on('enqueue', function () {
      console.log('Waiting for available connection slot');
    });
    关闭连接池

    之前提到关闭连接池中的连接后,当需要使用时连接池会自动新建,所以使用 connection.end() 或 connection.destroy() 时无法关闭连接池的,需要使用 pool.end() :

    pool.end(function (err) {
      // all connections in the pool have ended
    });
    查询语句

    在 Connection 或 Pool 实例上使用 .query() 是最简单的查询.

    第一种方式是直接拼接好查询用的sql .query(sqlString, callback)

    connection.query('SELECT * FROM `books` WHERE `author` = "David"', function (error, results, fields) {
      // error will be an Error if one occurred during the query
      // results will contain the results of the query
      // fields will contain information about the returned results fields (if any)
    });
    或者使用占位符,然后传参 .query(sqlString, values, callback)

    connection.query('SELECT * FROM `books` WHERE `author` = ?', ['David'], function (error, results, fields) {
      // error will be an Error if one occurred during the query
      // results will contain the results of the query
      // fields will contain information about the returned results fields (if any)
    });
    第三种方式是使用options. .query(options, callback)

    connection.query({
      sql: 'SELECT * FROM `books` WHERE `author` = ?',
      timeout: 40000, // 40s
      values: ['David']
    }, function (error, results, fields) {
      // error will be an Error if one occurred during the query
      // results will contain the results of the query
      // fields will contain information about the returned results fields (if any)
    });
    第二种和第三种使用方式可以混合使用

    connection.query({
        sql: 'SELECT * FROM `books` WHERE `author` = ?',
        timeout: 40000, // 40s
      },
      ['David'],
      function (error, results, fields) {
        // error will be an Error if one occurred during the query
        // results will contain the results of the query
        // fields will contain information about the returned results fields (if any)
      }
    );
    查询参数转义 Escaping query values

    为了避免sql注入攻击,在sql查询使用前,我们需要转义用户提供的任何数据. 使用 mysql.escape() , connection.escape() 或 pool.escape() 方法:

    var userId = 'some user provided value';
    var sql    = 'SELECT * FROM users WHERE id = ' connection.escape(userId);
    connection.query(sql, function(err, results) {
      // ...
    });
    使用占位符 ? ,也行.

    connection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) {
      // ...
    });
    占位符是按顺序替换的.

    connection.query('UPDATE users SET foo = ?, bar = ?, baz = ? WHERE id = ?', ['a', 'b', 'c', userId], function(err, results) {
      // ...
    });
    不同类型的参数,转义规则是不一样的:

    Numbers are left untouched
    Booleans are converted to true / false
    Date objects are converted to 'YYYY-mm-dd HH:ii:ss' strings
    Buffers are converted to hex strings, e.g. X'0fa5'
    Strings are safely escaped
    Arrays are turned into list, e.g. ['a', 'b'] turns into 'a', 'b'
    Nested arrays are turned into grouped lists (for bulk inserts), e.g. [['a', 'b'], ['c', 'd']] turns into ('a', 'b'), ('c', 'd')
    Objects are turned into key = 'val' pairs for each enumerable property on the object. If the property's value is a function, it is skipped; if the 
    property's value is an object, toString() is called on it and the returned value is used.
    undefined / null are converted to NULL
    NaN / Infinity are left as-is. MySQL does not support these, and trying to insert them as values will trigger MySQL errors until they implement 
    support.
    转义还提供对象方式传参数

    var post  = {id: 1, title: 'Hello MySQL'};
    var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
      // Neat!
    });
    console.log(query.sql); // INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'
    不嫌麻烦的话,咱们也可以自己手动转义:

    var query = "SELECT * FROM posts WHERE title=" mysql.escape("Hello MySQL");

    console.log(query); // SELECT * FROM posts WHERE title='Hello MySQL'
    转义查询的关键词 Escaping query identifiers

    如果你对用户提供的关键词没把我 (database / table / column name) ,可以使用 mysql.escapeId(identifier) ,

    connection.escapeId(identifier) or pool.escapeId(identifier) 转义:

    var sorter = 'date';
    var sql    = 'SELECT * FROM posts ORDER BY ' connection.escapeId(sorter);
    connection.query(sql, function(err, results) {
      // ...
    });
    var sorter = 'date';
    var sql    = 'SELECT * FROM posts ORDER BY ' connection.escapeId('posts.' sorter);
    connection.query(sql, function(err, results) {
      // ...
    });
    还可以使用 ?? 做占位符:

    var userId = 1;
    var columns = ['username', 'email'];
    var query = connection.query('SELECT ?? FROM ?? WHERE id = ?', [columns, 'users', userId], function(err, results) {
      // ...
    });

    console.log(query.sql); // SELECT `username`, `email` FROM `users` WHERE id = 1
    Please note that this last character sequence is experimental and syntax might change

    When you pass an Object to .escape() or .query() , .escapeId() is used to avoid SQL injection in object keys.

    准备查询语句Preparing Queries

    You can use mysql.format to prepare a query with multiple insertion points, utilizing the proper escaping for ids and values. A simple example of this follows:

    我们可以使用 mysql.format 来准备一个插入语句,解决转义问题.

    var sql = "SELECT * FROM ?? WHERE ?? = ?";
    var inserts = ['users', 'id', userId];
    sql = mysql.format(sql, inserts);
    这样我们就可以得到一个安全有效,转义好的查询语句. mysql.format 是 SqlString.format 暴露的,所以可以传入stringifyObject和timezone来自定义对象如何转为字符串.

    自定义格式 Custom format

    如果我们想使用其他方式来转义查询语句,可以使用connection的配置.可以使用内置的 .escape() 或其他配置函数.

    connection.config.queryFormat = function (query, values) {
      if (!values) return query;
      return query.replace(/:(w )/g, function (txt, key) {
        if (values.hasOwnProperty(key)) {
          return this.escape(values[key]);
        }
        return txt;
      }.bind(this));
    };

    connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" });
    获取插入行的id

    如果是id自增长方式插入数据,你可以这样获取id:

    connection.query('INSERT INTO posts SET ?', {title: 'test'}, function(err, result) {
      if (err) throw err;

      console.log(result.insertId);
    });
    When dealing with big numbers (above JavaScript Number precision limit), you should consider enabling supportBigNumbers option to be able to read the insert id as a string, otherwise it will throw an error.

    This option is also required when fetching big numbers from the database, otherwise you will get values rounded to hundreds or thousands due to the precision limit.

    获取影响的行数

    我们可以获取影响(新建,修改,删除)涉及的行数

    connection.query('DELETE FROM posts WHERE title = "wrong"', function (err, result) {
      if (err) throw err;

      console.log('deleted ' result.affectedRows ' rows');
    })
    获取修改的行数 Getting the number of changed rows

    我们可以获取update语句修改涉及的行数/

    "changedRows" 不同于 "affectedRows" 不统计符合条件但没有改变值的记录. in that it does not count updated rows whose values were not changed.

    connection.query('UPDATE posts SET ...', function (err, result) {
      if (err) throw err;

      console.log('changed ' result.changedRows ' rows');
    })
    获取连接id

    connection.connect(function(err) {
      if (err) throw err;
      console.log('connected as id ' connection.threadId);
    });
    并行执行查询

    mysql是顺序执行的,所以我们需要使用多个连接来并行查询.最简答的最法是每个http请求分配一个连接.

    流查询 Streaming query rows

    如果需要查询大量数据并处理每行,可以这样做:

    Sometimes you may want to select large quantities of rows and process each of them as they are received. This can be done like this:

    var query = connection.query('SELECT * FROM posts');
    query
      .on('error', function(err) {
        // Handle error, an 'end' event will be emitted after this as well
      })
      .on('fields', function(fields) {
        // the field packets for the rows to follow
      })
      .on('result', function(row) {
        // Pausing the connnection is useful if your processing involves I/O
        connection.pause();

        processRow(row, function() {
          connection.resume();
        });
      })
      .on('end', function() {
        // all rows have been received
      });
    Please note a few things about the example above:

    Usually you will want to receive a certain amount of rows before starting to 
    throttle the connection using pause() . This number will depend on the 
    amount and size of your rows.
    pause() / resume() operate on the underlying socket and parser. You are 
    guaranteed that no more 'result' events will fire after calling pause() .
    You MUST NOT provide a callback to the query() method when streaming rows.
    The 'result' event will fire for both rows as well as OK packets 
    confirming the success of a INSERT/UPDATE query.
    It is very important not to leave the result paused too long, or you may 
    encounter Error: Connection lost: The server closed the connection. 
    The time limit for this is determined by the 
    net_write_timeout setting 
    on your MySQL server.
    Additionally you may be interested to know that it is currently not possible to

    stream individual row columns, they will always be buffered up entirely. If you

    have a good use case for streaming large fields to and from MySQL, I'd love to

    get your thoughts and contributions on this.

    Piping results with Streams2

    The query object provides a convenience method .stream([options]) that wraps

    query events into a Readable

    Streams2 object. This

    stream can easily be piped downstream and provides automatic pause/resume,

    based on downstream congestion and the optional highWaterMark . The

    objectMode parameter of the stream is set to true and cannot be changed

    (if you need a byte stream, you will need to use a transform stream, like

    objstream for example).

    For example, piping query results into another stream (with a max buffer of 5

    objects) is simply:

    connection.query('SELECT * FROM posts')
      .stream({highWaterMark: 5})
      .pipe(...);
    多语句查询 Multiple statement queries

    由于sql注入的安全问题,多语句查询默认禁用.需要手动启用 {multipleStatements: true} .

    var connection = mysql.createConnection({multipleStatements: true});
    之后就跟普通使用是一样的.

    connection.query('SELECT 1; SELECT 2', function(err, results) {
      if (err) throw err;

      // `results` is an array with one element for every statement in the query:
      console.log(results[0]); // [{1: 1}]
      console.log(results[1]); // [{2: 2}]
    });
    Additionally you can also stream the results of multiple statement queries:

    var query = connection.query('SELECT 1; SELECT 2');

    query
      .on('fields', function(fields, index) {
        // the fields for the result rows that follow
      })
      .on('result', function(row, index) {
        // index refers to the statement this result belongs to (starts at 0)
      });
    If one of the statements in your query causes an error, the resulting Error

    object contains a err.index property which tells you which statement caused

    it. MySQL will also stop executing any remaining statements when an error

    occurs.

    Please note that the interface for streaming multiple statement queries is

    experimental and I am looking forward to feedback on it.

    存储过程 Stored procedures

    跟普通语句一样使用存储过程就好.如果存储过程返回了多个集合的数据,会像多语句查询那样返回结果集.

    join语句时相同列名处理 Joins with overlapping column names

    执行join语句时,很可能会收到重复的列名.

    By default, node-mysql will overwrite colliding column names in the

    order the columns are received from MySQL, causing some of the received values

    to be unavailable.

    However, you can also specify that you want your columns to be nested below

    the table name like this:

    var options = {sql: '...', nestTables: true};
    connection.query(options, function(err, results) {
      /* results will be an array like this now:
      [{
        table1: {
          fieldA: '...',
          fieldB: '...',
        },
        table2: {
          fieldA: '...',
          fieldB: '...',
        },
      }, ...]
      */
    });
    Or use a string separator to have your results merged.

    var options = {sql: '...', nestTables: '_'};
    connection.query(options, function(err, results) {
      /* results will be an array like this now:
      [{
        table1_fieldA: '...',
        table1_fieldB: '...',
        table2_fieldA: '...',
        table2_fieldB: '...',
      }, ...]
      */
    });
    事务 Transactions

    在connection中提供事务

    connection.beginTransaction(function(err) {
      if (err) { throw err; }
      connection.query('INSERT INTO posts SET title=?', title, function(err, result) {
        if (err) {
          return connection.rollback(function() {
            throw err;
          });
        }

        var log = 'Post ' result.insertId ' added';

        connection.query('INSERT INTO log SET data=?', log, function(err, result) {
          if (err) {
            return connection.rollback(function() {
              throw err;
            });
          }  
          connection.commit(function(err) {
            if (err) {
              return connection.rollback(function() {
                throw err;
              });
            }
            console.log('success!');
          });
        });
      });
    });
    beginTransaction(), commit() 和 rollback()只是简单执行START TRANSACTION, COMMIT, 和 ROLLBACK命令.而mysql中很多语句是可以自动提交的.自己翻 MySQL documentation

    Ping

    ping一下,确认连接是否有效,连接池也用.

    A ping packet can be sent over a connection using the connection.ping method. This

    method will send a ping packet to the server and when the server responds, the callback

    will fire. If an error occurred, the callback will fire with an error argument.

    connection.ping(function (err) {
      if (err) throw err;
      console.log('Server responded to ping');
    })
    Timeouts

    Every operation takes an optional inactivity timeout option. This allows you to

    specify appropriate timeouts for operations. It is important to note that these

    timeouts are not part of the MySQL protocol, and rather timeout operations through

    the client. This means that when a timeout is reached, the connection it occurred

    on will be destroyed and no further operations can be performed.

    // Kill query after 60s
    connection.query({sql: 'SELECT COUNT(*) AS count FROM big_table', timeout: 60000}, function (err, rows) {
      if (err && err.code === 'PROTOCOL_SEQUENCE_TIMEOUT') {
        throw new Error('too long to count table rows!');
      }

      if (err) {
        throw err;
      }

      console.log(rows[0].count ' rows');
    });
    Error handling

    This module comes with a consistent approach to error handling that you should

    review carefully in order to write solid applications.

    Most errors created by this module are instances of the JavaScript Error

    object. Additionally they typically come with two extra properties:

    err.code : Either a MySQL server error (e.g. 
    'ER_ACCESS_DENIED_ERROR' ), a Node.js error (e.g. 'ECONNREFUSED' ) or an 
    internal error (e.g. 'PROTOCOL_CONNECTION_LOST' ).
    err.fatal : Boolean, indicating if this error is terminal to the connection 
    object. If the error is not from a MySQL protocol operation, this properly 
    will not be defined.
    Fatal errors are propagated to all pending callbacks. In the example below, a

    fatal error is triggered by trying to connect to an invalid port. Therefore the

    error object is propagated to both pending callbacks:

    var connection = require('mysql').createConnection({
      port: 84943, // WRONG PORT
    });

    connection.connect(function(err) {
      console.log(err.code); // 'ECONNREFUSED'
      console.log(err.fatal); // true
    });

    connection.query('SELECT 1', function(err) {
      console.log(err.code); // 'ECONNREFUSED'
      console.log(err.fatal); // true
    });
    Normal errors however are only delegated to the callback they belong to. So in

    the example below, only the first callback receives an error, the second query

    works as expected:

    connection.query('USE name_of_db_that_does_not_exist', function(err, rows) {
      console.log(err.code); // 'ER_BAD_DB_ERROR'
    });

    connection.query('SELECT 1', function(err, rows) {
      console.log(err); // null
      console.log(rows.length); // 1
    });
    Last but not least: If a fatal errors occurs and there are no pending

    callbacks, or a normal error occurs which has no callback belonging to it, the

    error is emitted as an 'error' event on the connection object. This is

    demonstrated in the example below:

    connection.on('error', function(err) {
      console.log(err.code); // 'ER_BAD_DB_ERROR'
    });

    connection.query('USE name_of_db_that_does_not_exist');
    Note: 'error' events are special in node. If they occur without an attached

    listener, a stack trace is printed and your process is killed.

    tl;dr:This module does not want you to deal with silent failures. You

    should always provide callbacks to your method calls. If you want to ignore

    this advice and suppress unhandled errors, you can do this:

    // I am Chuck Norris:
    connection.on('error', function() {});
    Exception Safety

    This module is exception safe. That means you can continue to use it, even if

    one of your callback functions throws an error which you're catching using

    'uncaughtException' or a domain.

    Type casting

    For your convenience, this driver will cast mysql types into native JavaScript

    types by default. The following mappings exist:

    Number

    TINYINT
    SMALLINT
    INT
    MEDIUMINT
    YEAR
    FLOAT
    DOUBLE
    Date

    TIMESTAMP
    DATE
    DATETIME
    Buffer

    TINYBLOB
    MEDIUMBLOB
    LONGBLOB
    BLOB
    BINARY
    VARBINARY
    BIT (last byte will be filled with 0 bits as necessary)
    String

    Notetext in the binary character set is returned as Buffer , rather

    than a string.

    CHAR
    VARCHAR
    TINYTEXT
    MEDIUMTEXT
    LONGTEXT
    TEXT
    ENUM
    SET
    DECIMAL (may exceed float precision)
    BIGINT (may exceed float precision)
    TIME (could be mapped to Date, but what date would be set?)
    GEOMETRY (never used those, get in touch if you do)
    It is not recommended (and may go away / change in the future) to disable type

    casting, but you can currently do so on either the connection:

    var connection = require('mysql').createConnection({typeCast: false});
    Or on the query level:

    var options = {sql: '...', typeCast: false};
    var query = connection.query(options, function(err, results) {

    });
    You can also pass a function and handle type casting yourself. You're given some

    column information like database, table and name and also type and length. If you

    just want to apply a custom type casting to a specific type you can do it and then

    fallback to the default. Here's an example of converting TINYINT(1) to boolean:

    connection.query({
      sql: '...',
      typeCast: function (field, next) {
        if (field.type == 'TINY' && field.length == 1) {
          return (field.string() == '1'); // 1 = true, 0 = false
        }
        return next();
      }
    });
    WARNING: YOU MUST INVOKE the parser using one of these three field functions in your custom typeCast callback. They can only be called once. (see #539 for discussion)

    field.string()
    field.buffer()
    field.geometry()
    are aliases for

    parser.parseLengthCodedString()
    parser.parseLengthCodedBuffer()
    parser.parseGeometryValue()
    You can find which field function you need to use by looking at: RowDataPacket.prototype._typeCast

    Connection Flags

    If, for any reason, you would like to change the default connection flags, you

    can use the connection option flags . Pass a string with a comma separated list

    of items to add to the default flags. If you don't want a default flag to be used

    prepend the flag with a minus sign. To add a flag that is not in the default list,

    just write the flag name, or prefix it with a plus (case insensitive).

    Please note that some available flags that are not supported (e.g.: Compression), 
    are still not allowed to be specified.

    Example

    The next example blacklists FOUND_ROWS flag from default connection flags.

    var connection = mysql.createConnection("mysql://localhost/test?flags=-FOUND_ROWS");
    Default Flags

    The following flags are sent by default on a new connection:

    CONNECT_WITH_DB - Ability to specify the database on connection.
    FOUND_ROWS - Send the found rows instead of the affected rows as affectedRows .
    IGNORE_SIGPIPE - Old; no effect.
    IGNORE_SPACE - Let the parser ignore spaces before the ( in queries.
    LOCAL_FILES - Can use LOAD DATA LOCAL .
    LONG_FLAG
    LONG_PASSWORD - Use the improved version of Old Password Authentication.
    MULTI_RESULTS - Can handle multiple resultsets for COM_QUERY.
    ODBC Old; no effect.
    PROTOCOL_41 - Uses the 4.1 protocol.
    PS_MULTI_RESULTS - Can handle multiple resultsets for COM_STMT_EXECUTE.
    RESERVED - Old flag for the 4.1 protocol.
    SECURE_CONNECTION - Support native 4.1 authentication.
    TRANSACTIONS - Asks for the transaction status flags.
    In addition, the following flag will be sent if the option multipleStatements 
    is set to true :

    MULTI_STATEMENTS - The client may send multiple statement per query or

    statement prepare.

    Other Available Flags

    There are other flags available. They may or may not function, but are still

    available to specify.

    COMPRESS
    INTERACTIVE
    NO_SCHEMA
    PLUGIN_AUTH
    REMEMBER_OPTIONS
    SSL
    SSL_VERIFY_SERVER_CERT
    Debugging and reporting problems

    If you are running into problems, one thing that may help is enabling the

    debug mode for the connection:

    var connection = mysql.createConnection({debug: true});
    This will print all incoming and outgoing packets on stdout. You can also restrict debugging to

    packet types by passing an array of types to debug:

    var connection = mysql.createConnection({debug: ['ComQueryPacket', 'RowDataPacket']});
    to restrict debugging to the query and data packets.

    If that does not help, feel free to open a GitHub issue. A good GitHub issue

    will have:

    The minimal amount of code required to reproduce the problem (if possible)
    As much debugging output and information about your environment (mysql 
    version, node version, os, etc.) as you can gather.
    Running tests

    The test suite is split into two parts: unit tests and integration tests.

    The unit tests run on any machine while the integration tests require a

    MySQL server instance to be setup.

    Running unit tests

    $ FILTER=unit npm test
    Running integration tests

    Set the environment variables MYSQL_DATABASE , MYSQL_HOST , MYSQL_PORT ,

    MYSQL_USER and MYSQL_PASSWORD . MYSQL_SOCKET can also be used in place

    of MYSQL_HOST and MYSQL_PORT to connect over a UNIX socket. Then run

    npm test .

    For example, if you have an installation of mysql running on localhost:3306

    and no password set for the root user, run:

    $ mysql -u root -e "CREATE DATABASE IF NOT EXISTS node_mysql_test"
    $ MYSQL_HOST=localhost MYSQL_PORT=3306 MYSQL_DATABASE=node_mysql_test MYSQL_USER=root MYSQL_PASSWORD= FILTER=integration npm test

    您可能感兴趣的文章:
    mysql数据库备份常用命令示例
    在ubuntu下使用mysql常用命令
    Nodejs进程管理模块forever用法详解
    ubuntu下mysql配置
    忘记MySql的root密码的解决方法
    shell脚本向mysql表批量插入数据
    windows下mysql主从复制配置
    mysql授权远程访问的例子
    收集了一些mysql常用命令
    导出mysql 数据结构的例子

  • 相关阅读:
    leetcode 437. 路径总和 III
    leetcode 113. 路径总和 II
    题解 【CF387B】George and Round
    题解 【CF489B】 BerSU Ball
    题解【2.23考试T3】val
    题解【2.23考试T1】div
    题解 【洛谷P4290】 [HAOI2008]玩具取名
    题解 【洛谷P1035】[NOIP2002]级数求和
    题解【洛谷P1046】[NOIP2005] 陶陶摘苹果
    题解【洛谷P1618】 三连击(升级版)
  • 原文地址:https://www.cnblogs.com/long613/p/7790692.html
Copyright © 2011-2022 走看看