Node.js與MySQL交互操作有很多庫(kù)设塔,具體可以在 https://www.npmjs.com/package/mysql 查看。
安裝
npm install mysql
測(cè)試MySQL
自己下載mysql安裝就不說(shuō)明了远舅,很簡(jiǎn)單的壹置。
用官方的例子好了
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});//創(chuàng)建mysql鏈接
connection.connect();
connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});//執(zhí)行sql語(yǔ)句
connection.end();//關(guān)閉鏈接
認(rèn)識(shí)一下Connection Options
要想創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)連接,先就要認(rèn)識(shí)清楚Options
host:主機(jī)地址 (默認(rèn):localhost)
user:用戶名
password:密碼
port:端口號(hào) (默認(rèn):3306)
database:數(shù)據(jù)庫(kù)名
charset:連接字符集(默認(rèn):'UTF8_GENERAL_CI'表谊,注意字符集的字母都要大寫)
localAddress:此IP用于TCP連接(可選)
socketPath:連接到unix域路徑钞护,當(dāng)使用 host 和 port 時(shí)會(huì)被忽略
timezone:時(shí)區(qū)(默認(rèn):'local')
connectTimeout:連接超時(shí)(默認(rèn):不限制;單位:毫秒)
stringifyObjects:是否序列化對(duì)象(默認(rèn):'false' 爆办;與安全相關(guān)(https://github.com/felixge/node-mysql/issues/501)
typeCast:是否將列值轉(zhuǎn)化為本地JavaScript類型值 (默認(rèn):true)
queryFormat:自定義query語(yǔ)句格式化方法 (https://github.com/felixge/node-mysql#custom-format)
supportBigNumbers:數(shù)據(jù)庫(kù)支持bigint或decimal類型列時(shí)难咕,需要設(shè)此option為true (默認(rèn):false)
bigNumberStrings:supportBigNumbers和bigNumberStrings啟用 強(qiáng)制bigint或decimal列以JavaScript字符串類型返回(默認(rèn):false)
dateStrings:強(qiáng)制timestamp,datetime,data類型以字符串類型返回,而不是JavaScript Date類型(默認(rèn):false)
debug:開啟調(diào)試(默認(rèn):false)
multipleStatements:是否許一個(gè)query中有多個(gè)MySQL語(yǔ)句 (默認(rèn):false)
flags:用于修改連接標(biāo)志,更多詳情:(https://github.com/felixge/node-mysql#connection-flags)
ssl:使用ssl參數(shù)(與crypto.createCredenitals參數(shù)格式一至)或一個(gè)包含ssl配置文件名稱的字符串余佃,目前只捆綁Amazon RDS的配置文件
增暮刃、刪、改爆土、查
增椭懊、刪、改步势、查主要是sql語(yǔ)句來(lái)定的氧猬。
1.增加
var userAddSql = 'INSERT INTO userinfo(Id,UserName,UserPass) VALUES(0,?,?)';
var userAddSql_Params = ['Wilson', 'abcd'];
connection.query(userAddSql,userAddSql_Params,function (err, result) {
...
});
2.刪除
var userModSql = 'DELETE FROM userinfo';
connection.query(userModSql,function (err, result) {
...
});
3.修改
var userModSql = 'UPDATE userinfo SET UserName = ?,UserPass = ? WHERE Id = ?';
var userModSql_Params = ['鐘慰', '5678',1];
connection.query(userModSql,userModSql_Params,function (err, result) {
...
});
4.查詢
var userGetSql = 'SELECT * FROM userinfo';
connection.query(userGetSql ,function (err, result) {
...
});
結(jié)束數(shù)據(jù)庫(kù)連接兩種方法和區(qū)別
前面的示例中我在結(jié)尾處都會(huì)調(diào)用一個(gè)connection.end()方法,這個(gè)方法connection.connect()對(duì)應(yīng),一個(gè)開始坏瘩,一個(gè)結(jié)束盅抚!
結(jié)束連接其實(shí)有兩種方法end(),destory()倔矾;
end()方法在queries都結(jié)束后執(zhí)行妄均,end()方法接收一個(gè)回調(diào)函數(shù)还棱,queries執(zhí)行出錯(cuò)丈甸,仍然后結(jié)束連接,錯(cuò)誤會(huì)返回給回調(diào)函數(shù)err參數(shù)垦巴,可以在回調(diào)函數(shù)中處理壤巷!
destory()比較暴力烫沙,沒(méi)有回調(diào)函數(shù),即刻執(zhí)行隙笆,不管queries是否完成!
斷線重連
var mysql = require('mysql');
var db_config = {
host : '192.168.0.200',
user : 'root',
password : 'abcd',
port: '3306',
database: 'nodesample'
};
var connection;
function handleDisconnect() {
connection = mysql.createConnection(db_config);
connection.connect(function(err) {
if(err) {
console.log("進(jìn)行斷線重連:" + new Date());
setTimeout(handleDisconnect, 2000); //2秒重連一次
return;
}
console.log("連接成功");
});
connection.on('error', function(err) {
console.log('db error', err);
if(err.code === 'PROTOCOL_CONNECTION_LOST') {
handleDisconnect();
} else {
throw err;
}
});
}
handleDisconnect();
sql鏈接池Pooling connections
1.連接池的創(chuàng)建升筏,使用createPool方法撑柔,options和createConntion一致,可以監(jiān)聽connection事件.
連接池會(huì)自動(dòng)斷線重連
var mysql = require('mysql');
//創(chuàng)建連接池
var pool = mysql.createPool({
host : '192.168.0.200',
user : 'root',
password : 'abcd'
});
//監(jiān)聽connection事件
pool.on('connection', function(connection) {
connection.query('SET SESSION auto_increment_increment=1');
});
連接池可以直接使用您访,也可以共享一個(gè)連接或管理多個(gè)連接(引用官方示例)
//直接使用
pool.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
if (err) throw err;
console.log('The solution is: ', rows[0].solution);
});
//共享
pool.getConnection(function(err, connection) {
// connected! (unlesserr
is set)
});
2.其它連接池配置選項(xiàng)
waitForConnections
當(dāng)連接池沒(méi)有連接或超出最大限制時(shí)铅忿,設(shè)置為true且會(huì)把連接放入隊(duì)列,設(shè)置為false會(huì)返回error
connectionLimit 連接數(shù)限制灵汪,默認(rèn):10
queueLimit 最大連接請(qǐng)求隊(duì)列限制檀训,設(shè)置為0表示不限制,默認(rèn):0
3.釋放
調(diào)用connection.release()方法享言,會(huì)把連接放回連接池峻凫,等待其它使用者使用!
其它...
1. escape()
防止SQL注入,可以使用pool.escape()和connect.escape()览露,不多說(shuō)了荧琼,自已可以試試
這樣使用 'SELECT * FROM userinfo WHERE id = ' + pool.escape('5 OR ID = 6')
2.escapeId()
如果不能信任SQL標(biāo)識(shí)符(數(shù)據(jù)庫(kù)名、表名、列名)命锄,可以使用轉(zhuǎn)換方法escapeId()堰乔;
類似這樣 'SELECT * FROM posts ORDER BY ' + connect.escapeId("date");
3.format()
可以使用mysql.format來(lái)準(zhǔn)備查詢語(yǔ)句,該函數(shù)會(huì)自動(dòng)的選擇合適的方法轉(zhuǎn)義參數(shù)脐恩。
var sql = "SELECT * FROM ? WHERE ? = ?";
var inserts = ['users', 'id', 123];
sql = mysql.format(sql, inserts);
4.自定義格式化函數(shù)
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" });