node-mysql文檔翻譯

模塊Github地址

安裝

npm install mysql

如果需要以前的版本0.9.x系列的文檔,請訪問v0.9 branch.
有時你可以從github中安裝最新版本的node-mysql,具體怎麼做請參考下面的示例:

npm install felixge/node-mysql

介紹

這是一個node.Js的mysql驅動程序。這個驅動完全是用javascript寫的,不需要任何編譯工作。完全的遵守MIT開源協議。
這裏有一個簡單的示例告訴你如何使用它:

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

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(); //釋放連接

從上面這個例子中,你應該要知道如下的兩點:

  1. 每個方法調用在連接隊列中是按順序執行。
  2. 當使用 end() 函數關閉連接時候,你必須要確保你的所有查詢都已經發送給了mysql服務器。否者end()之後的查詢是無效的。

創建連接

推薦的一種連接方式:

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

connection.connect(function(err) {
// 成功連接! (unless err is set)
});

然而,一個連接只能隱式的調用一個query函數。調用方式如下:

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

connection.query('SELECT 1', function(err, rows) {
// 成功連接! (unless err is set)
});

上面的兩種錯誤處理方法都合適,這取決於你更喜歡那一種方式來做數據庫錯誤信息處理。任何一種連接上的錯誤(握手與網絡)都會被視爲致命錯誤,具體更多的錯誤處理信息可以查看Error Handling章節。

連接可選參數

當我們使用Node-MySQL建立一個數據庫連接的時候你可以通過下面這些選項:

參數名 代表值
host 數據庫的主機名(默認: localhost
port 數據庫服務器的端口(默認: 3306)
localAddress 使用TCP連接的源IP地址(可選)
socketPath 使用Unix域套接字連接的路徑,當使用 host 與 port 的時候可以忽略。
user 這個是MySQL身份驗證的用戶名。
password MySQL用戶的密碼。
database 連接的數據庫名(可選).
charset 連接之後的字符編碼(默認:' UTF8_GENERAL_CI',值得提醒的是,這個值必須都是大寫字母).
timezone 這個是儲存數據的是當前時間。(默認:local).
connectTimeout MySQL初始連接的超時時間。單位是毫秒(默認:無超時限制)。
stringifyObjects 把值轉換爲 Stringify 對象。(默認:false)。
insecureAuth 允許使用老(不安全)的身份認證方式去連接MySQL數據庫.(默認: false).
typeCast 是否把結果值轉換爲原生的 javascript 類型(默認: true).
queryFormat 一個可以自己定義查詢格式函數(具體見Custom format)。
supportBigNumbers 當在數據庫中處理一個大數(BIGINT和DECIMAL)數據類型的時候,你需要啓用這個選項(默認: false).
dateStrings 強制爲date類型(TIMESTAMP,DATETIME,DATE)轉化爲一個字符串返回而不是轉換成 javascript的date類型對象。(默認: false)
debug 答應協議詳細信息到標準輸出(默認: false).
trace 產生棧跟蹤當在庫的入口點出現error時,當調用數次很多時性能會略微下降(默認: true).
multipleStatements 允許每個mysql語句有多條查詢.使用它時要非常注意,因爲它很容易引起sql注入攻擊(默認:false).
flags 使用連接標示符號標示出超過默認的值的連接。它也可以加到默認的黑名單連接中。更多信息參考(Connection Flags)。
ssl 使用ssl參數對象(格式參考crypto.createCredentials參數)或者是用一個包含ssl配置的字符串名。目前僅僅支持亞馬遜的ca證書,參考:https://rds.amazonaws.com/doc/rds-ssl-ca-cert.pem
bigNumberStrings 這個選項需要bigNumberStrings與 supportBigNumbers同時啓用,強制把數據庫中大數(BIGINT和DECIMAL)數據類型的值轉換爲javascript字符對象串對象返回。(默認:false)。當啓用supportBigNumbers選項,但 bigNumberStrings是未啓用的狀態。當無法用javascript數字對象(JavaScript Number objects)所表達的時候就會返回的是一個big number字符串對象(值的範圍要在 [-253, +253]之間).否則將會返回一個Number類型的對象。如果supportBigNumbers是false那麼這個選項會被自動忽略。

除了利用這些選項來做對象使用,你也可以用一個字符串來標示。例如:

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

注意:查詢出來的值第一會嘗試轉換爲json格式,如果轉換失敗.那麼就會轉換成純文本的字符串.

關閉連接

有兩種關閉連接的方式,當查詢完成後最優雅關閉連接方式是調用end()方法,例如:

connection.end(function(err) {
// 連接在這裏會被終止
});

這樣可以確保在查詢隊列完成之後發送一個 COM_QUIT 包到mysql服務器。如果在發送 COM_QUIT 出現致命的錯誤。在回調函數裏面有一個err參數可以使用。但是這個連接無論如何也會被關閉掉。

另外一種替代end()方法的是調用destroy()方法,這個方法會立即終止底層socket連接.destroy()方法確保了沒有任何事件或回調再連接觸發。

connection.destroy();

destroy()方法不像end()方法, destroy()方法是沒有任何回調參數的。

連接池

直接使用連接池

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

pool.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
  if (err) throw err;
  console.log('The solution is: ', rows[0].solution);
});

連接可以輕易的共享一個連接或者是管理多個連接:

var mysql = require('mysql');
var pool = mysql.createPool({
  host : 'example.org',
  user : 'bob',
  password : 'secret'
});
pool.getConnection(function(err, connection) {
// 連接成功! (除非有err )
});

如果你想在連接前設置session變量並且獲取使用。你可以監聽connection事件:

pool.on('connection', function(connection) {
  connection.query('SET SESSION auto_increment_increment=1')
});

當你的連接完成後,只需要調用connection.release()方法。將連接返回到池中,以供其他人再次使用。

var mysql = require('mysql');
var pool = mysql.createPool(...);
pool.getConnection(function(err, connection) {
  // 使用連接
connection.query( 'SELECT something FROM sometable', function(err, rows) {
  // 連接使用完成後釋放連接
  connection.release();
    // 不要在這裏使用connection進行查詢,因爲連接已經被歸還到連接池了
  });
});

如果你想關閉連接並且從連接池中移除,使用connection.destory()方法代替。當你下一次需要使用的時候,池會自動創建一個新的連接。
通過池創建連接是非常緩慢的。如果你配置你的連接池最大的連接數爲100,當你只需要同時使用5個連接時候,它也僅僅只會創建5個連接。這種連接的循環方式是一種輪詢(round-robin)的方式。採取的是從連接池頂部到底部的方式。

Pool參數選項

池連可以接受一些連接的參數選項。當一個連接創建之後,這些參數選項通過簡單的構造傳遞到連接裏面。池連接參數可以接受下面這些參數。waitForConnections:判斷當前的連接是否可用並且是否已經達到了連接數的上限。如果是true。這個連接就會加入到連接隊列中同時把狀態轉換爲可用狀態。如果是false,那麼會立即返回一個錯誤給開發者。(默認:true).connectionLimit:一次連接最大的連接數(默認:10)。queueLimit:從getConnection獲取連接數並且判斷是否超出了queneLimit限制的排隊等待的連接值,如果是就返回一個錯誤。如果設置爲0,就是不限制連隊列數(默認:0)。

PoolCluster

PoolCluster提供了多臺主機連接功能(group&retry&selector):

// 創建連接
var poolCluster = mysql.createPoolCluster();
poolCluster.add(config); // anonymous group
poolCluster.add('MASTER', masterConfig);
poolCluster.add('SLAVE1', slave1Config);
poolCluster.add('SLAVE2', slave2Config);

// 目標主機組 : ALL(anonymous, MASTER, SLAVE1-2), 連接方式 : round-robin(default)
poolCluster.getConnection(function (err, connection) {});

// 目標主機組 : MASTER, 連接方式: round-robin
poolCluster.getConnection('MASTER', function (err, connection) {});

// 目標主機組 : SLAVE1-2, 連接方式 : order
// 如果不能連接到SLAVE1就連接SLAVE2(把SLAVE1從集羣節點中刪除)
poolCluster.on('remove', function (nodeId) {
  console.log('REMOVED NODE : ' + nodeId); // 節點ID= SLAVE1 
});

poolCluster.getConnection('SLAVE*', 'ORDER', function (err, connection) {
});

// 命名方式: of(pattern, selector)
poolCluster.of('*').getConnection(function (err, connection) {
});

var pool = poolCluster.of('SLAVE*', 'RANDOM');
pool.getConnection(function (err, connection) {
});

pool.getConnection(function (err, connection) {
});

// 釋放連接
poolCluster.end();

PoolCluster選項

參數名 代表值
canRetry 如果是true,當連接失敗時Poolcluster會嘗試重新連接(默認:true)。
removeNodeErrorCount 如果連接失敗,節點的errorCount將會增加.當errorCount大於removeNodeErrorCount時,會從poolCluster中移除一個節點。(默認:5).
defaultSelector 默認選擇器(默認:RR).
RR 選擇一個交替(輪循)
RANDOM 由隨機函數選擇一個節點.
ORDER 按照順序無條件的選擇第一個節點。
var clusterConfig = {
  removeNodeErrorCount: 1, // 連接失敗後立即從把該節點移除
  defaultSelector: 'ORDER'
};

var poolCluster = mysql.createPoolCluster(clusterConfig);

切換用戶/修改連接狀態

MySQL提供了ChangeUser的命令,允許你更改當前用戶並且切換用戶時不需要關閉底層socket連接:

connection.changeUser({user : 'john'}, function(err) {
  if (err) throw err;
});

這個功能提供了幾個有用的參數選項:

參數名 代表值
user 新用戶的名字。(默認爲切換新用戶前第一個用戶)
password 新用戶的密碼(默認爲切換新用戶前第一個用戶)
charset 新的字符編碼(默認爲切換新用戶前第一個用戶)
database 新的數據庫名(默認爲切換新用戶前第一個用戶)

這個功能有時有一個副作用,它會把所有的連接狀態都重置(變量,事務).
注意:此操作出現的錯誤會被該模塊視爲致命錯誤處理。

服務器連接斷開

由於網絡問題你有可能丟失與MySQL服務器的連接。也有可能被服務器踢出連接,還有可能是服務器重啓或是崩潰等等,這些都是致命的錯誤都被歸爲error對象裏面。並且模塊提供了err.code = 'PROTOCOL_CONNECTION_LOST'信息,更多的錯誤處理信息請參考Error Handling 。
與服務器重連是建立一個新的連接,一旦現在的連接斷開就不能讓這個連接重新連接。它必須重新建立一條連接,連接到數據庫服務器。
在連接池裏面,當連接斷開時會從連接池裏面把連接移除,當下次需要連接的時候調用getConnection創建一個新的連接。

轉義查詢值

爲了避免被SQL注入攻擊,你需要把用戶提交過來的數據進行轉義之後再放到SQL查詢語句裏面。模塊提供了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) {
  // ...
});

這看起來像是使用了MySQL的預處理語句,其實同樣的在MySQL內部也是使用了類似connection.escape()的方法。
不同的是類型轉義的值不同。請看下面的解釋:

  1. Number類型保存不變.
  2. Boolean值被轉換爲了true/false字符串.
  3. Date類型被轉換爲了'YYYY-mm-dd HH:ii:ss'字符串
  4. Buffer轉換爲了16進制,例如:X'0fa5'
  5. String轉換爲了安全的字符串。
  6. Array轉換爲了list。例如:['a','b']會返回'a','b'
  7. 多維數組會被轉換爲多維list。例如[['a', 'b'], ['c', 'd']]返回('a', 'b'), ('c', 'd')
  8. Object轉換爲key = 'val';多維Object對象會轉換爲字符串.
  9. undefined/null會轉換爲null
  10. NaN / Infinity 保持不變,因爲MySQL現在並不支持這些對象,如果你把NaN/Infinity做爲值,MySQL會報錯.直到它們被MySQL支持。

如果你留意了,你會發現轉義查詢值可以巧妙的用下面這種方式:

var post = {id: 1, title: 'Hello MySQL'};
var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
  // 非常完美!
});
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'

轉義查詢標示符
如果你不信任用戶提交過來的標示符((database / table / column name))。那麼你需要使用mysql.escapeId(identifier)來轉義:

var sorter = 'date';
var query = 'SELECT * FROM posts ORDER BY ' + mysql.escapeId(sorter);
console.log(query); // SELECT * FROM posts ORDER BY date

它還支持添加合格的轉義符。不過得把轉義的分成兩部分:

var sorter = 'date';
var query = 'SELECT * FROM posts ORDER BY ' + mysql.escapeId('posts.' + sorter);
console.log(query); // SELECT * FROM posts ORDER BY posts.date

或者,你可以使用佔位符'??',它會自動轉義查詢的值:

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(),.query(),.escapeId()時可以有效的防禦SQL注入攻擊.

預查詢

你可以使用mysql.format()去執行預處理多嵌套查詢語句,利用適當的轉義處理對於標示符與值.下面有一個簡單的例子:

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

這種方法可以確保發送到數據庫進行數據查詢之前就能夠保證查詢語句的安全,在發送到數據庫查詢之前執行預查詢,這個功能非常的有用。
由於mysql.format是由sql的String.format暴露出來的。所以你可以你還可以選擇傳遞stringifyObject 和timezone對象(不強制要求)。
並且允許您自定義把對象轉換字符串的方法。以及特定地區的時間和時區(location specific/timezone aware Date).

自定義格式

如果您喜歡其他樣式的轉義格式。你可以在連接配置選項中自定義你的功能函數。如果你還想使用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。你可以這樣獲取:

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

當處理大數字的時候(超過javascriptNumber類型的精度),你需要啓用supportBigNumbers以便把ID作爲字符串類型讀取。否者會拋出錯誤.
而且當從數據庫中查詢的數字是一個big number類型的時候,你也需要把supportBigNumbers選項設置爲true,否則查詢出來的數據在傳輸過來的時候由於精度限制,自動刪除超出部分。

執行並行查詢

MySQL的協議是順序執行的。所以這就意味這你需要建立多個連接去實現並行查詢,你應該需要一個池(Pool)來管理連接。一個簡單的方法就是每一個連接都創建的一個HTTP請求連接.

數據流查詢

有時,你可能去執行一個大的查詢,並且要處理查詢返回的每一行結果。那麼你可以嘗試這樣做:

var query = connection.query('SELECT * FROM posts');
query.on('error', function(err) {
  // 處理錯誤,當出現錯誤時,會立即發出一個end事件
  }).on('fields', function(fields) {
    // the field packets for the rows to follow
  }).on('result', function(row) {
    // 處理工程中涉及到I/O可以在這裏先暫停連接
    connection.pause();
    processRow(row, function() {
    connection.resume();
    });
  }).on('end', function() {
    // 獲取所有查詢內容
  });

在上面的例子中請注意幾件事情:

  1. 同常的時候你希望當接收到一定數量的查詢結果的時候再執行pause()方法,這數量取決於你查詢總的數量和數據的大小。
  2. pause()/resume()操作底層socket和解析器時,可以確定在調用pause()方法之後再有result事件被執行。
  3. 當有多條數據流讀取時,不能再給query()方法添加一個回調函數。
  4. 在'result'事件中不僅可以返回查詢的數據也可以確認query/INSERT執行是否成功。
  5. 除此之外,你應該有興趣知道當前的模塊並不支持單獨一行的流讀取。它們都是被緩存起來當SQL執行完之後一併把結果返回過來。假如你有在大型的案例中應用到了MySQL的流技術。我很想能夠與您分享。

管道結果(Piping results)和Streams2

query對象提供了一個非常方便的方法.stream(可選).它把查詢事件封裝成了可讀(Readable)的Streams2對象,此流可以很容易地通過管道downstream,並提供自動化暫停/恢復,基於downstream堵塞和可選highWaterMark。該流的objectMode參數默認設爲true 。

例如,把查詢結果通過piping導入到另一個流中(最大緩存爲5)的簡單例子:

connection.query('SELECT * FROM posts')
.stream({highWaterMark: 5})
.pipe(...);

多語句查詢

出於安全考慮,多語句查詢默認是禁用的.(如果值沒有經過轉義,那麼很有可能會導致SQL注入攻擊)。如果你想使用此功能,你必須在連接中啓用它:

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

如果你有一個查詢語句出現了錯誤,那麼拋出的錯誤會包含在err.index屬性裏面並且會告訴你是哪條語句出現了錯誤。同時當發生錯誤時對於剩餘的查詢語句MySQL也會停止執行.

注意:目前利用流來執行多條查詢語句的接口還在試驗階段。所以我很期待能夠得到您的反饋。

儲存過程

你可以在你的查詢語句裏面調用MySQL驅動中自帶的任何存儲過程,如果你使用存儲過程生成的多個結果集,其實也就與您使用多語句查詢生成得出的結果是一樣的。

合併重疊的字段

當我們使用JOIN函數執行查詢的時候得到的結果裏面有很多字段是重複的。默認情況下Node-MySQL會按照列讀取順序把一些衝突的列名進行合併。但是這樣有可能會導致一些接收到的值變得不可用。
不過,您可以指定在表名中嵌套您需要的列,就像這樣:

var options = {sql: '...', nestTables: true};
connection.query(options, function(err, results) {
  /* 結果將會像下面這樣的數組形式返回: 
  [{
  table1: {
    fieldA: '...',
    fieldB: '...',
  },
  table2: {
    fieldA: '...',
    fieldB: '...',
  }, 
  }, ...]
  */
});

或者你可以使用字符串分隔符合併成你想要的結果:

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: '...',
},...]
*/
});

事務處理

在連接層中可以支持簡單的事務處理:

connection.beginTransaction(function(err) {
  if (err) { throw err; }
  connection.query('INSERT INTO posts SET title=?', title, function(err, result) {
    if (err) { 
      connection.rollback(function() {
        throw err;
      });
    }
    
    var log = 'Post ' + result.insertId + ' added';
    connection.query('INSERT INTO log SET data=?', log, function(err, result) {
      if (err) { 
        connection.rollback(function() {
          throw err;
        });
      }
    
      connection.commit(function(err) {
        if (err) { 
          connection.rollback(function() {
            throw err;
          });
        }
        console.log('success!');
      });
    });
  });
});

請注意,執行START TRANSACTION, COMMIT,和 ROLLBACK 這些簡單命令的方法分別是transaction(),Commit()和rollback(),瞭解MySQL中一些會造成隱式提交語句很重要。

錯誤處理

這個模塊包含了錯誤處理機制,不過在編碼的時候你還應該去自己檢查自己的代碼。看看是否會有一些意想不到的錯誤。
這個模塊中所有的錯誤都是javascript error的對象實例,同時它還有兩個屬性:

  1. err.code: 任一的MySQL錯誤 MySQL server error (例如. 'ER_ACCESS_DENIED_ERROR'), Node.js錯誤 (例如.'ECONNREFUSED') 或者是內部錯誤 (e.g. 'PROTOCOL_CONNECTION_LOST').

  2. err.fatal:布爾值,這個對象表示是否能夠連接到服務器.

  3.  

致命的錯誤都可以在回調函數中捕獲到。在下面這個例子中,所引起的錯誤是因爲改連接試圖連接到一個無效的端口上面。因此錯誤對象會被傳遞到回調函數中並且能夠使用err.code或err.fatal知道錯誤的具體情況:

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

最後值得提醒的是,有時候你可以把錯誤處理不放在與查詢一起的回調函數裏面,就如同上面的那個例子。你可以把錯誤處理放在連接對象上的錯誤事件裏面。就像下面這樣:

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中是一個特殊的對象,如果它沒有被掛在一個事件上而是單獨出現,那麼就很有可能出現堆棧錯誤並且關閉NodeJS程序進程.
最後:這個模塊處理錯誤的初衷都不是悄悄的處理掉錯誤,你應該把錯誤的處理放在回調函數裏面。但是如果你不喜歡這麼麻煩並且忽略掉錯誤。那麼你可以這樣做:

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

異常安全處理

這個模塊的異常處理很安全,也就是說在回調函數中拋出一個錯誤之後你可以使用’uncaughtException‘或域(domain)去捕獲錯誤,然後繼續的去使用做下面的事情。

類型轉換

爲了您的使用方面,這個驅動會自動把MySQL中的一些類型轉換爲原生的javascript的類型。下面列舉的是轉換的類型:
Number:

  • TINYINT
  • SMALLINT
  • INT
  • MEDIUMINT
  • YEAR
  • FLOAT
  • DOUBLE

Date:

  • TIMESTAMP
  • DATE
  • DATETIME

Buffer:

  • TINYBLOB
  • MEDIUMBLOB
  • LONGBLOB
  • BLOB
  • BINARY
  • VARBINARY
  • BIT (最後一個字節會使用0來填充)

String:

  • CHAR
  • VARCHAR
  • TINYTEXT
  • MEDIUMTEXT
  • LONGTEXT
  • TEXT
  • ENUM
  • SET
  • DECIMAL (可能會超過float精度)
  • BIGINT (可能會超過float精度)
  • TIME (轉換爲日期, but what date would be set?)
  • GEOMETRY (從來沒有用錯,當你使用的時候你可以聯繫我們)

我們不建議你把類型轉換這個參數禁用,但是如果你想禁用也可以在連接的時候就去做(這種方法可能在以後的版本中刪除/改變):

var connection = require('mysql').createConnection({typeCast:false});

或者在查詢層做:

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

});

你也可以通過一個處理函數來轉換自己想要的類型,通過已知的一些字段的信息,像數據庫,表名和字段名,數據類型和長度。如果你只想自己定義一個類型轉換函數。你可以在查詢的回調函數中做。例如你把TINYINT(1)轉換爲布爾值:

connection.query({
sql: '...',
typeCast: function (field, next) {
if (field.type == 'TINY' && field.length == 1) {
return (field.string() == '1'); // 1 = true, 0 = false
}
return next();
}});

警告:你必須使用解析器中內建的三個field函數中的一個,在你自定義的類型轉換回調函數中。他們只能調用一次:

field.string()
field.buffer()
field.geometry()
//或者使用別名:
parser.parseLengthCodedString()
parser.parseLengthCodedBuffer()
parser.parseGeometryValue()

如果你需要使用field函數,。你可以在RowDataPacket.prototype._typeCast中找到關於field函數的一些文檔資料

連接標記

如果,由於某些原因你需要修改默認的連接標記,那麼你可能需要使用flags選項。通過在連接配置的選項列表中添加這個選項,那麼你就可以修改默認的連接標記.如果你不想使用默認的flag你可以使用一個減號來取消掉。或者在連接的配置選項列表裏面添加一個flag選項,而不寫值,僅僅就是一個flag名字在哪裏(不區分大小寫)。
PS:不想像去掉flag選項一樣在flag的前面加一個+號:

請注意:有些默認的flag目前還不支持(例如:SSL,Compression)。

例子:
下面的例子是使用黑名單FOUND_ROWS flag例子:

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

默認標記:

  • LONG_PASSWORD
  • FOUND_ROWS
  • LONG_FLAG
  • CONNECT_WITH_DB
  • ODBC
  • LOCAL_FILES
  • IGNORE_SPACE
  • PROTOCOL_41
  • IGNORE_SIGPIPE
  • TRANSACTIONS
  • RESERVED
  • SECURE_CONNECTION
  • MULTI_RESULTS
  • MULTI_STATEMENTS (如果使用 multipleStatements 選項就激活)

其他的可用標記:

  • NO_SCHEMA
  • COMPRESS
  • INTERACTIVE
  • SSL
  • PS_MULTI_RESULTS
  • PLUGIN_AUTH
  • SSL_VERIFY_SERVER_CERT
  • REMEMBER_OPTIONS

調試與問題查看

如果在運行過程中出現了問題,你可以在連接的配置選項中添加一個debug參數來幫助你調試:

var connection = mysql.createConnection({debug: true});

它會將輸入的信息與輸出的信息標準輸出的顯示出來,你還可以通過把數據包的類型轉換成一個數據數組對象來方便調試:

var connection = mysql.createConnection({debug: ['ComQueryPacket', 'RowDataPacket']});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章