node.js中怎么操作mysql數(shù)據(jù)庫,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

準(zhǔn)備工作
在使用node操作mysql數(shù)據(jù)庫時,需要先下載mysql模塊:
npm install mysql --save-dev
在引入mysql模塊后,就可以進(jìn)行數(shù)據(jù)庫的連接和其他的操作了。
// test.js
var mysql = require('mysql');一、連接數(shù)據(jù)庫
首先保證本地已經(jīng)安裝數(shù)據(jù)庫,并已正常啟動,然后開始進(jìn)行連接:
// test.js
var mysql = require('mysql');
// 創(chuàng)建連接
var conn = mysql.createConnection({
host : '127.0.0.1',
user : 'root',
password : '123',
database : 'test'
});
// 創(chuàng)建連接后不論是否成功都會調(diào)用
conn.connect(function(err){
if(err) throw err;
console.log('connect success!');
});
// 其他的數(shù)據(jù)庫操作,位置預(yù)留
// 關(guān)閉連接時調(diào)用
conn.end(function(err){
if(err) throw err;
console.log('connect end');
})執(zhí)行node test.js后,就會輸出:
$ node test.js connect success! connect end
連接成功,然后連接關(guān)閉。這就說明程序可以正常連接數(shù)據(jù)庫了,然后就開始進(jìn)行增刪改查的操作。
二、CURD
比如我們有這樣的一個user表,里面有4個字段,其中uid是自增字段:
| uid | username | password | |
| 1 | meizi | meizi | 123@qq.com |
| 2 | test | test | 456@qq.com |
我們就對這個表進(jìn)行增刪改查的操作。
mysql中有個query方法可以用來執(zhí)行任意正確的sql語句,然后在回調(diào)函數(shù)里給出執(zhí)行sql語句后的結(jié)果。query方法是異步執(zhí)行的,若并列書寫多個query方法的話,是不能按照書寫順序依次阻塞式執(zhí)行的。
2.1 查詢
使用最普遍最多的就是查詢操作了。
conn.query('SELECT * FROM `user`', function(err, result, fields){
if(err) throw err;
console.log(result);
});
console.log( 'select ended!' );輸出的結(jié)果:
select ended! // 先輸出
[
RowDataPacket {
uid: 1,
username: 'meizi',
password: 'meizi
email: '123@qq.com'
},
RowDataPacket {
uid: 2,
username: 'test',
password: 'test
email: '456@qq.com'
}
]可以看到,結(jié)果集是一個數(shù)組,數(shù)組中的每條數(shù)據(jù)都是一個RowDataPacket對象,在使用時,可以像json對象一樣獲取數(shù)據(jù),也可以使用JSON.stringify把result轉(zhuǎn)換為json字符串,但是,result并不是JSON數(shù)據(jù)。而且,即使結(jié)果集中只有一條數(shù)據(jù),也是以數(shù)組的形式返回的。
console.log(result[0].username); // meizi
輸出即為字符串類型的數(shù)據(jù)。
2.2 添加
向數(shù)據(jù)庫中添加數(shù)據(jù)使用的是INSERT,INSERT語句有兩種形式都可以使用:
第1種,先列好要插入的數(shù)據(jù)對應(yīng)的字段,然后跟上數(shù)據(jù)(如果要給所有的字段都插入數(shù)據(jù),可以省略字段不寫,但是數(shù)據(jù)的書寫順序要跟數(shù)據(jù)表里的字段一一對應(yīng)):
INSERT INTO table_name ( field1, field2,...fieldN ) VALUES ( value1, value2,...valueN );
第2種,可以像update操作一樣書寫,將field與value對應(yīng)的更緊密:
INSERT INTO table_name SET field1=value1, field2=value2, ... fieldN=valueN;
我更加喜歡第2種方式,這種方式更能看出操作了哪些字段,看出字段和數(shù)據(jù)的對應(yīng)關(guān)系。在node中插入數(shù)據(jù):
conn.query("INSERT INTO `user` SET `username`='qwerty', `password`='741', `email`='qwerty@qq.com'", function(err, result){
if(err) throw err;
console.log(result);
});插入數(shù)據(jù)后返回的結(jié)果是:
OkPacket {
fieldCount: 0,
affectedRows: 1,
insertId: 4, // 數(shù)據(jù)插入成功時,對應(yīng)的主鍵id
serverStatus: 2,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0
}affectedRows表示數(shù)據(jù)表中受影響的行數(shù),數(shù)據(jù)插入成功則為1,失敗則為0;在主鍵自增的情況下,insertId是數(shù)據(jù)插入成功后對應(yīng)的主鍵id,如果主鍵不自增,則insertId為0。
2.3 更新
使用update語句更新數(shù)據(jù):
// 更新uid的密碼
conn.query('UPDATE `user` SET `password`="123456" WHERE `uid`=4', function(err, result){
if(err) throw err;
console.log(result);
});輸出的結(jié)果:
OkPacket {
fieldCount: 0,
affectedRows: 1,
insertId: 0,
serverStatus: 2,
warningCount: 0,
message: '(Rows matched: 1 Changed: 1 Warnings: 0',
protocol41: true,
changedRows: 1
}可以看到輸出結(jié)果的類型與插入數(shù)據(jù)時輸出結(jié)果的類型是一樣的。我們分析一下,執(zhí)行sql語句后,有3種結(jié)果:
成功修改數(shù)據(jù): affectedRows:1, changedRows:1
要修改的數(shù)據(jù)與原數(shù)據(jù)相同: affectedRows:1, changedRows:0
未找到需要修改的數(shù)據(jù): affectedRows:0, changedRows:0
因此可以根據(jù)這兩個字段輸出相應(yīng)的結(jié)果。
2.4 刪除
使用delete語句刪除語句:
conn.query('DELETE FROM `user` WHERE `uid`=4', function(err, result, fields){
if(err) throw err;
console.log(result);
});輸出的結(jié)果:
OkPacket {
fieldCount: 0,
affectedRows: 1,
insertId: 0,
serverStatus: 2,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0
}刪除成功,則affectedRows為1,刪除的數(shù)據(jù)不存在,則為0。
三、連接池
數(shù)據(jù)庫連接是一種有限的,能夠顯著影響到整個應(yīng)用程序的伸縮性和健壯性的資源,在多用戶的網(wǎng)頁應(yīng)用程序中體現(xiàn)得尤為突出。
數(shù)據(jù)庫連接池正是針對這個問題提出來的,它會負(fù)責(zé)分配、管理和釋放數(shù)據(jù)庫連接,允許應(yīng)用程序重復(fù)使用一個現(xiàn)有的數(shù)據(jù)庫連接,而不是重新建立一個連接,釋放空閑時間超過大允許空閑時間的數(shù)據(jù)庫連接以避免因為連接未釋放而引起的數(shù)據(jù)庫連接遺漏。
3.1 創(chuàng)建連接池
使用mysql.createPool()可創(chuàng)建連接池:
// test.js
var mysql = require('mysql');
var pool = mysql.createPool({
host : '127.0.0.1',
user : 'root',
password : '123',
database : 'test'
})
pool.query('SELECT * FROM `user`', function(err, result){
if(err) throw err;
console.log(result);
pool.end(function(err){
if(err) throw err;
console.log('connection ended');
})
});getConnection()可以共享一個連接,或管理多個連接。
// test.js
var mysql = require('mysql');
var pool = mysql.createPool({
host : '127.0.0.1',
user : 'root',
password : '123',
database : 'test'
})
pool.getConnection(function(err, connection){
if(err) throw err;
connection.query('SELECT * FROM `user`', function(err, result){
if(err) throw err;
console.log(result);
})
});連接使用完后通過調(diào)用connection.release()方法可以將連接返回到連接池中,這個連接可以被其它人重復(fù)使用:
pool.getConnection(function(err, connection){
if(err) throw err;
connection.query('SELECT * FROM `user`', function(err, result){
if(err) throw err;
console.log(result);
connection.release();
// 接下來connection已經(jīng)無法使用,它已經(jīng)被返回到連接池中
})
});可以使用connection.destroy()徹底銷毀連接。
3.2 連接池事件
createPool()方法會返回一個連接池實例對象,這個對象中有一些事件。
connection
連接池中產(chǎn)生新連接時會發(fā)送'connection'事件:
pool.on('connection', function (connection) {
console.log('new connection');
});3.3 QUERY與GETCONNECTION的區(qū)別
這兩個方法都能進(jìn)行操作,那么這兩者有什么區(qū)別呢?
在pool.getConnection中的connection在其回調(diào)函數(shù)里是一直的,可以保證這一系列的操作都是在同一個connection中執(zhí)行的;pool.query則每次執(zhí)行時可能會在不同的connection中執(zhí)行,可能會得到意想不到的結(jié)果。
比如SQL_CALC_FOUND_ROWS和FOUND_ROWS這需要兩個sql語句完成,是獲取檢索行的數(shù)目。
pool.query('SELECT SQL_CALC_FOUND_ROWS * FROM `user`');
pool.query('SELECT FOUND_ROWS()');這兩個可能在不同的connection中執(zhí)行,第2個sql語句返回的就不是上一個sql語句的結(jié)果了。
四、sql防注入
sql防注入的關(guān)鍵就是不能直接把數(shù)據(jù)拼接到sql語句中,必須得對數(shù)據(jù)進(jìn)行轉(zhuǎn)義,或者使用提供的方法拼接sql語句。這里主要有四種方法可以使用。
4.1 使用ESCAPE()對參數(shù)進(jìn)行編碼
參數(shù)編碼方法有:mysql.escape()/connection.escape()/pool.escape(),這三個方法可以在你需要的時候調(diào)用:
var sql = 'SELECT * FROM `user` WHERE `uid`='+connection.escape('"123";//--');
console.log(sql); // SELECT * FROM `user` WHERE `uid`='\"123\";//--'
connection.query(sql, function(err, result){
if(err) throw err;
console.log(result);
})對雙引號進(jìn)行了安全轉(zhuǎn)義。
escapeId()可以對不信任的表名,字段名進(jìn)行轉(zhuǎn)義。
var sql = 'SELECT * FROM '+connection.escapeId('user')+' WHERE `uid`=1';
connection.query(sql, function(err, result){
console.log(result);
})
console.log(query.sql); // SELECT * FROM `user` WHERE `uid`=1同時,escape()的編碼規(guī)則如下:
Numbers不進(jìn)行轉(zhuǎn)換
Booleans轉(zhuǎn)換為true/false
Date對象轉(zhuǎn)換為'YYYY-mm-dd HH:ii:ss'字符串
Buffers轉(zhuǎn)換為hex字符串,如X'0fa5'
Strings進(jìn)行安全轉(zhuǎn)義
Arrays轉(zhuǎn)換為列表,如[‘a(chǎn)', ‘b']會轉(zhuǎn)換為'a', ‘b'
多維數(shù)組轉(zhuǎn)換為組列表,如[[‘a(chǎn)', ‘b'], [‘c', ‘d']]會轉(zhuǎn)換為(‘a(chǎn)', ‘b'), (‘c', ‘d')
Objects會轉(zhuǎn)換為key=value鍵值對的形式。嵌套的對象轉(zhuǎn)換為字符串
undefined/null會轉(zhuǎn)換為NULL
MySQL不支持NaN/Infinity,并且會觸發(fā)MySQL錯誤
4.2 占位符
可以使用?作為參數(shù)占位符。在使用查詢參數(shù)占位符時,在其內(nèi)部自動調(diào)用connection.escape()方法對傳入?yún)?shù)進(jìn)行編碼。
var params = ['test', 'test'];
var query = connection.query('SELECT * FROM `user` WHERE `username`=? AND `password`=?', params, function(err, result){
console.log(result);
});
console.log(query.sql); // SELECT * FROM `user` WHERE `username`='test' AND `password`='test'同時,如果執(zhí)行添加或更新操作時,還可以這樣寫:
var params = {username:'qwerty', password:'qwerty', email:'qwerty@qq.com'};
var query = connection.query('INSERT INTO `user` SET ?', params, function(err, result){
if(err) throw err;
console.log(result);
});
console.log(query.sql); // INSERT INTO `user` SET `username` = 'qwerty', `password` = 'qwerty', `email` = 'qwerty@qq.com'數(shù)據(jù)庫中的表明和字段名,可以使用??作為占位符,在拼接完成后會自動添加上``:
var params = ['user', 'username', 'test', 'password', 'test'];
var query = connection.query('SELECT * FROM ?? WHERE ??=? AND ??=?', params, function(err, result){
console.log(result);
})
console.log(query.sql); // SELECT * FROM `user` WHERE `username`='test' AND `password`='test'4.3 使用MYSQL.FORMAT()轉(zhuǎn)義參數(shù)
不多說,樣例如下:
var userId = 1; var sql = "SELECT * FROM ?? WHERE ?? = ?"; var inserts = ['user', 'uid', userId]; sql = mysql.format(sql, inserts); // SELECT * FROM `user` WHERE `uid` = 1
五、多語句查詢
出于安全考慮node-mysql默認(rèn)禁止多語句查詢(可以防止SQL注入),啟用多語句查詢可以將multipleStatements選項設(shè)置為true:
var connection = mysql.createConnection({multipleStatements: true});啟用后可以在一個query查詢中執(zhí)行多條語句:
connection.query('SELECT 1; SELECT 2', function(err, results) {
if (err) throw err;
// `results`是一個包含多個語句查詢結(jié)果的數(shù)組
console.log(results[0]);
console.log(results[1]);
});看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)建站的支持。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站chinadenli.net,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、建站服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
當(dāng)前名稱:node.js中怎么操作mysql數(shù)據(jù)庫-創(chuàng)新互聯(lián)
網(wǎng)頁地址:http://chinadenli.net/article16/cecpgg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、云服務(wù)器、面包屑導(dǎo)航、小程序開發(fā)、服務(wù)器托管、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)