安裝
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(); //釋放連接
從上面這個例子中,你應該要知道如下的兩點:
- 每個方法調用在連接隊列中是按順序執行。
- 當使用
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()的方法。
不同的是類型轉義的值不同。請看下面的解釋:
- Number類型保存不變.
- Boolean值被轉換為了true/false字符串.
- Date類型被轉換為了'YYYY-mm-dd HH:ii:ss'字符串
- Buffer轉換為了16進制,例如:X'0fa5'
- String轉換為了安全的字符串。
- Array轉換為了list。例如:['a','b']會返回'a','b'
- 多維數組會被轉換為多維list。例如[['a', 'b'], ['c', 'd']]返回('a', 'b'), ('c', 'd')
- Object轉換為key = 'val';多維Object對象會轉換為字符串.
- undefined/null會轉換為null
- 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() {
// 獲取所有查詢內容
});
在上面的例子中請注意幾件事情:
- 同常的時候你希望當接收到一定數量的查詢結果的時候再執行pause()方法,這數量取決于你查詢總的數量和數據的大小。
- pause()/resume()操作底層socket和解析器時,可以確定在調用pause()方法之后再有result事件被執行。
- 當有多條數據流讀取時,不能再給query()方法添加一個回調函數。
- 在'result'事件中不僅可以返回查詢的數據也可以確認query/INSERT執行是否成功。
- 除此之外,你應該有興趣知道當前的模塊并不支持單獨一行的流讀取。它們都是被緩存起來當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中一些會造成隱式提交語句很重要。
錯誤處理
這個模塊包含了錯誤處理機制,不過在編碼的時候你還應該去自己檢查自己的代碼??纯词欠駮幸恍┮庀氩坏降腻e誤。
這個模塊中所有的錯誤都是javascript error的對象實例,同時它還有兩個屬性:
err.code: 任一的MySQL錯誤 MySQL server error (例如. 'ER_ACCESS_DENIED_ERROR'), Node.js錯誤 (例如.'ECONNREFUSED') 或者是內部錯誤 (e.g. 'PROTOCOL_CONNECTION_LOST').
err.fatal:布爾值,這個對象表示是否能夠連接到服務器.
致命的錯誤都可以在回調函數中捕獲到。在下面這個例子中,所引起的錯誤是因為改連接試圖連接到一個無效的端口上面。因此錯誤對象會被傳遞到回調函數中并且能夠使用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你可以使用一個減號來取消掉?;蛘咴谶B接的配置選項列表里面添加一個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']});