您好,登錄后才能下訂單哦!
前言
我們在上一篇文章《Node.js數(shù)據(jù)庫操作之連接MySQL數(shù)據(jù)庫(一)》中已經(jīng)學習了Nodejs連接MySQL數(shù)據(jù)庫的幾種方法,數(shù)據(jù)庫連接上了之后就需要對數(shù)據(jù)庫進行查詢。本篇文章介紹一下查詢MySQL數(shù)據(jù)庫的方法。下面話不多說,來看看詳細的介紹吧。
查詢方式
上一篇文章中,我們用到了一種查詢數(shù)據(jù)庫的最基本的方法:connection.query(sqlString, callback)
。
第一個參數(shù)是一個SQL語句,可以是任意的數(shù)據(jù)庫語句,而第二個參數(shù)是一個回調函數(shù),查詢結果通過回調參數(shù)的方式返回。
connection.query( 'select * from book where author = "xyf" and country = "china"', function(err, result) { console.log(result); } );
這是最簡單的查詢方式,但是存在著兩個問題,一個是需要拼接字符串,比較繁瑣;另一個是容易被sql注入攻擊,因此我們有了第二種查詢方式。
占位符注入查詢
第二種查詢方式是采用了占位符的形式connection.query(sqlString, values, callback)
,這樣就不需要進行惡心的字符串的拼接了。
connection.query( 'select * from book where author = ? and country = ?', ['xyf', 'china'], function(err, result) { console.log(result); } );
使用對象查詢方式
第三種查詢方式我們將查詢語句和查詢值組合成一個對象來進行查詢。它的形式是這樣的:connection.query(object, callback)
。
connection.query( { sql: 'select * from book where author = ? and country = ?', values: ['xyf', 'china'], // 作為對象的屬性 timeout: 40000, }, function(err, result) { console.log(result); } );
組合查詢方式
將第二種和第三種方式可以結合起來使用,查詢值作為query方法的一個參數(shù),而不是作為對象中的一個屬性。
connection.query( { sql: 'select * from book where author = ? and country = ?', timeout: 40000, // ['corner', 'us'] // 如果同時設置,那么此時不會生效 }, ['xyf', 'china'], // 作為query函數(shù)的一個參數(shù) function(err, result) { console.log(result); } );
需要注意的是,如果我們既將查詢值作為對象的屬性,又將其作為query函數(shù)的參數(shù),這個時候函數(shù)中的參數(shù)將會覆蓋對象的屬性,也就是說此時只有參數(shù)的值生效。
解析查詢值
在進行數(shù)據(jù)庫查詢時,有一個重要的原則就是永遠不要相信用戶的輸入。為什么不能相信用戶的輸入呢,首先讓我們來了解一下SQL注入攻擊。
SQL注入攻擊
所謂的SQL注入攻擊,就是通過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執(zhí)行惡意的SQL命令。由于筆者并不是從事數(shù)據(jù)庫方面的工作,也不是數(shù)據(jù)庫方面的磚家,所以只能通過一個簡單的DEMO來演示一下SQL注入攻擊。
假如我們拼接的SQL語句是這樣的
var username = 'xyf'; var sql = 'select * from book where author = "'+username+'"';
這里我們期待用戶輸入的username是Jack或者LiLi之類的,但是用戶說我偏不,我就輸入一串惡意代碼:
var username = '"1 or 1=1'; var sql = 'select * from book where author = "'+username+'"';
最后我們拼接的查詢語句就變成了下面這樣的:
select * from book where author = "" or 1=1
如果讀者對SQL語句有一些基本了解,就會知道如果把這段查詢語句放到數(shù)據(jù)庫中進行查詢,那么所有用戶的信息都被查出來了,但是這并不是我們想要看到的結果。
避免SQL注入攻擊
那么怎么才能避免SQL注入攻擊呢?mysql提供了兩種方法給我們,第一種方法就是每次查詢時都把用戶輸入的數(shù)據(jù)都用escape()函數(shù)解析一下,有點類似預處理語句。
var authorname = 'user input'; connection.escape(authorname); // 或者使用mysql.escape(authorname); connection.query( 'select * from book where author = "'+authorname+'"', function(err, result) { console.log(result); } );
第二種方法就是在查詢時通過上面說到的占位符注入查詢的查詢方式來進行查詢。但它內(nèi)部的實現(xiàn)也是通過上面所說的escape()方法將用戶輸入解析了一下。推薦使用第二種方法來得簡單快捷。
多語句查詢
mysql還支持多語句查詢,但是由于某些安全原因(官方解釋是因為如果值沒有正確解析會導致SQL注入攻擊)默認是被禁止的。那么讓我們來打開這個“潘多拉魔盒”把。
在創(chuàng)建數(shù)據(jù)庫連接時首先把這個功能開啟。
let connection = mysql.createConnection({ // 其他配置 multipleStatements: true, });
然后我們就可以使用多語句查詢了。
connection.query( { sql: `select * from book where username = ?; select * from book where username = ?;`, }, ['ace','xyf'], function(err, rows, fields) { if (err) throw err; console.log('The solution is: ', rows); } );
查詢結果
通過查詢語句返回的結果以數(shù)組的形式返回,如果是單語句查詢,數(shù)組就是一個純對象數(shù)組[obj1,obj2,...],數(shù)組中的每一個對象都是數(shù)據(jù)庫中每一行的數(shù)據(jù),只是以對象的方式返回。如果沒有查詢到數(shù)據(jù),那么數(shù)組的長度就為0。
但是如果是多語句(m條語句)的方式查詢,雖然返回也是一個數(shù)組,但是數(shù)組中嵌套有n個數(shù)組,n的取值取決于你查詢語句的條數(shù)m(即n=m)。
總結
由于官方文檔比較零碎,因此整理得不是很到位,有問題的地方希望大家指正。以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。