程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> nodemysql部分中文文檔

nodemysql部分中文文檔

編輯:MySQL綜合教程

nodemysql部分中文文檔


這基於是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中很特殊。如果他們出現而沒有綁定偵聽器,會打印堆棧跟蹤並且殺死你的進程。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved