码迷,mamicode.com
首页 > 数据库 > 详细

node mysql 部分中文文档

时间:2015-05-28 11:01:11      阅读:350      评论:0      收藏:0      [点我收藏+]

标签:javascript   node   mysql   

这基于是node-mysql官方文档的部分中文翻译,由于最近要在nodejs上使用mysql,看文档的时候顺带把这个文档部分翻译了,无责任翻译,不齐全也可能有些地方不对,不好勿喷。

node-mysql 项目地址
我的博客

安装

安装稳定版本:

$ npm install mysql

安装最新版本:

$ npm install felixge/node-mysql

介绍

这是一个用Javascript编写的Node.js链接Mysql数据库的驱动模块。

建立连接

建立连接的一种推荐方法:

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)
});

连接选项(Connection options)

在建立一个连接时,可以使用以下选项:

host:主机地址 (默认:localhost)

user:用户名

password:密码

port:端口号 (默认:3306)

database:数据库名

charset:连接字符集(默认:’UTF8_GENERAL_CI’,注意字符集的字母都要大写)

localAddress:此IP用于TCP连接(可选)

socketPath:连接到unix域路径,当使用 host 和 port 时会被忽略

timezone:时区(默认:’local’)

connectTimeout:连接超时(默认:不限制;单位:毫秒)

stringifyObjects:是否序列化对象(默认:’false’ ;与安全相关https://github.com/felixge/node-mysql/issues/501

typeCast:是否将列值转化为本地JavaScript类型值 (默认:true)

queryFormat:自定义query语句格式化方法 https://github.com/felixge/node-mysql#custom-format

supportBigNumbers:数据库支持bigint或decimal类型列时,需要设此option为true (默认:false)

bigNumberStrings:supportBigNumbers和bigNumberStrings启用 强制bigint或decimal列以JavaScript字符串类型返回(默认:false)

dateStrings:强制timestamp,datetime,data类型以字符串类型返回,而不是JavaScript Date类型(默认:false)

debug:开启调试(默认:false)

multipleStatements:是否许一个query中有多个MySQL语句 (默认:false)

flags:用于修改连接标志,更多详情:https://github.com/felixge/node-mysql#connection-flags

ssl:使用ssl参数(与crypto.createCredenitals参数格式一至)或一个包含ssl配置文件名称的字符串,目前只捆绑Amazon RDS的配置文件

  其它:

  可以使用URL形式的加接字符串,不多介绍了,不太喜欢那种格式,觉得可读性差,也易出错,想了解的可以去主页上看。

关闭连接

可以通过两种方式关闭数据库连接。

通过 end() 方法按照正常状态关闭已经完成的数据库连接:

connection.end(function(err) {
  // The connection is terminated now
});

另外一种可选的方法是通过 destroy() 方法
这种方法会即刻执行,不管queries是否完成!

connection.destroy();

end() 不同的是, destroy() 方法不接受callback

查询

建立一个查询的最基本的方法是在一个连接实例(像Connection, Pool, PoolNamespace 或其他相似的对象)上调用 .query() 方法

query() 最简单的形式是 .query(sqlString, callback), 第一个参数是SQL语句,第二个参数是回调函数:

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)
});

第三种形式 .query(options, callback) 是在查询中使用多种选项参数, 如 escaping query values,joins with overlapping column names,timeouts, 和type casting:

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)
});

注意当占位符作为参数传递而不是对象时,第二跟第三种形式可以结合来使用。

values 参数会覆盖掉选项对象中的 values

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)
  }
);

编码查询值

为了防止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.escape() 方法

如果你留意的话, 你可能会注意到这可以使得你的语句变得简洁:

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‘

如果你想自己进行编码,你也可以直接使用 escaping 函数:

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

console.log(query); // SELECT * FROM posts WHERE title=‘Hello MySQL‘

编码查询标志符

如果你不相信用户提供的查询标志符 (database / table / column name) , 你可以使用 mysql.escapeId(identifier),
connection.escapeId(identifier)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

你可以传递一个对象给 .escape() or .query(), .escapeId() 来避免SQL注入。

创建查询语句

你可以使用 mysql.format 来创建一个多插入点的查询语句,对id和值适当的编码 。一个简单的例子:

var sql = "SELECT * FROM ?? WHERE ?? = ?";
var inserts = [‘users‘, ‘id‘, userId];
sql = mysql.format(sql, inserts);

这样你可以获得一个有效并且安全的查询语句

自定义格式

如果你喜欢另外一个查询编码格式, 有一个连接选项可以让你定义一个自定义的格式。
一个实现自定义格式的例子:

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:

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

  console.log(result.insertId);
});

当处理大数字(在JavaScript数精度上),你应该考虑启用supportbignumbers选项把ID作为字符串读取插入,否则将会抛出错误。
在从数据库取大数时也要启用这个选项

获取受影响的行数

你可以获得从插入,更新或删除语句受影响的行数。

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

  console.log(‘deleted ‘ + result.affectedRows + ‘ rows‘);
})

获取被改变的行数

你可以获得更新语句被改变的行数。

“changedRows”不同于 “affectedRows” 在于他不算没有被改变的值

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

  console.log(‘changed ‘ + result.changedRows + ‘ rows‘);
})

获得连接ID

你可以使用threadId属性获取MySQL连接ID(“thread ID”)。

connection.connect(function(err) {
  if (err) throw err;
  console.log(‘connected as id ‘ + connection.threadId);
});

多语句查询

由于安全原因,默认是关闭的.
如果要用需要这样创建连接:

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}]
});

此外,你还可以这样:

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)
  });

如果你的一个查询语句导致错误,由此产生 Error
err.index 属性就是你第几条语句出错
当发生错误时MySQL也将停止执行其余的语句。

错误处理

该模块自带了错误处理,为了写出健壮的应用,你应该仔细看。

通过本模块创建的所有错误是JavaScript的Error对象实例
。他们有两个属性:

  • err.code: MySQL 错误码 (e.g.‘ER_ACCESS_DENIED_ERROR‘), node.js错误 (e.g. ‘ECONNREFUSED‘) 或者内部错误 (e.g. ‘PROTOCOL_CONNECTION_LOST‘).*
  • err.fatal: 布尔值, 指出这个错误是否是终端连接对象。

Error: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error
MySQL server error: http://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html

致命错误会挂起所有的回调。在下面的例子中,试图连接到一个无效端口时触发致命的错误。因此,错误传递到回调:

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
});

正常错误只返回给属于他们回调函数。所以在下面的例子中,只有第一个回调会接收错误,第二个查询的会出错:

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
});

如果一个致命的错误产生,没有一个待定的回调,或者当一个正常的错误产生而没有属于他的回调,错误会向连接对象发出error事件。下面的例子说明:

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

connection.query(‘USE name_of_db_that_does_not_exist‘);

注:error事件在 node中很特殊。如果他们出现而没有绑定侦听器,会打印堆栈跟踪并且杀死你的进程。

node mysql 部分中文文档

标签:javascript   node   mysql   

原文地址:http://blog.csdn.net/huangxiongbiao/article/details/46116901

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!