最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

從零學(xué)習(xí)node.js之mysql數(shù)據(jù)庫的操作(五)

 更新時間:2017年02月24日 08:41:03   作者:Wenzi  
因為接觸Node.JS已經(jīng)有一段時間了,最近粗略的研究了一下node.js操作數(shù)據(jù)庫的包,覺得node.js連接數(shù)據(jù)庫不錯。下面這篇文章主要給大家介紹了node.js之mysql數(shù)據(jù)庫操作的相關(guān)資料,需要的朋友可以參考下。

準(zhǔn)備工作

在使用node操作mysql數(shù)據(jù)庫時,需要先下載mysql模塊:

npm install mysql --save-dev

在引入mysql模塊后,就可以進行數(shù)據(jù)庫的連接和其他的操作了。

// test.js
var mysql = require('mysql');

一、連接數(shù)據(jù)庫

首先保證本地已經(jīng)安裝數(shù)據(jù)庫,并已正常啟動,然后開始進行連接:

// 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ù)庫了,然后就開始進行增刪改查的操作。

二、CURD

比如我們有這樣的一個user表,里面有4個字段,其中uid是自增字段:

uid username password email
1 meizi meizi 123@qq.com
2 test test 456@qq.com

我們就對這個表進行增刪改查的操作。

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é)果:

  1. 成功修改數(shù)據(jù): affectedRows:1, changedRows:1
  2. 要修改的數(shù)據(jù)與原數(shù)據(jù)相同: affectedRows:1, changedRows:0
  3. 未找到需要修改的數(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ū)別

這兩個方法都能進行操作,那么這兩者有什么區(qū)別呢?

pool.getConnection中的connection在其回調(diào)函數(shù)里是一直的,可以保證這一系列的操作都是在同一個connection中執(zhí)行的;pool.query則每次執(zhí)行時可能會在不同的connection中執(zhí)行,可能會得到意想不到的結(jié)果。

比如SQL_CALC_FOUND_ROWSFOUND_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ù)進行轉(zhuǎn)義,或者使用提供的方法拼接sql語句。這里主要有四種方法可以使用。

4.1 使用ESCAPE()對參數(shù)進行編碼

參數(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);
})

對雙引號進行了安全轉(zhuǎn)義。

escapeId()可以對不信任的表名,字段名進行轉(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ī)則如下:

  1. Numbers不進行轉(zhuǎn)換
  2. Booleans轉(zhuǎn)換為true/false
  3. Date對象轉(zhuǎn)換為'YYYY-mm-dd HH:ii:ss'字符串
  4. Buffers轉(zhuǎn)換為hex字符串,如X'0fa5'
  5. Strings進行安全轉(zhuǎn)義
  6. Arrays轉(zhuǎn)換為列表,如[‘a(chǎn)', ‘b']會轉(zhuǎn)換為'a', ‘b'
  7. 多維數(shù)組轉(zhuǎn)換為組列表,如[[‘a(chǎn)', ‘b'], [‘c', ‘d']]會轉(zhuǎn)換為(‘a(chǎn)', ‘b'), (‘c', ‘d')
  8. Objects會轉(zhuǎn)換為key=value鍵值對的形式。嵌套的對象轉(zhuǎn)換為字符串
  9. undefined/null會轉(zhuǎn)換為NULL
  10. MySQL不支持NaN/Infinity,并且會觸發(fā)MySQL錯誤

4.2 占位符

可以使用?作為參數(shù)占位符。在使用查詢參數(shù)占位符時,在其內(nèi)部自動調(diào)用 connection.escape() 方法對傳入?yún)?shù)進行編碼。

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

總結(jié)

本節(jié)只是總結(jié)了node對mysql數(shù)據(jù)庫的各種操作,但如果實際應(yīng)用起來的話,還遠遠不夠。努力學(xué)習(xí)中…希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

相關(guān)文章

  • Node.js實現(xiàn)mysql連接池使用事務(wù)自動回收連接的方法示例

    Node.js實現(xiàn)mysql連接池使用事務(wù)自動回收連接的方法示例

    這篇文章主要介紹了Node.js實現(xiàn)mysql連接池使用事務(wù)自動回收連接的方法,結(jié)合實例形式分析了node.js操作mysql連接池實現(xiàn)基于事務(wù)的連接回收操作相關(guān)技巧,需要的朋友可以參考下
    2018-02-02
  • 用Nodejs實現(xiàn)在終端中炒股的實現(xiàn)

    用Nodejs實現(xiàn)在終端中炒股的實現(xiàn)

    這篇文章主要介紹了用Nodejs實現(xiàn)在終端中炒股的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • yarn安裝依賴速度太慢的解決辦法

    yarn安裝依賴速度太慢的解決辦法

    本文介紹如何通過修改配置文件解決yarn安裝依賴速度太慢的問題,文中通過圖文結(jié)合講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-12-12
  • pnpm的安裝及其使用教程(匯總)

    pnpm的安裝及其使用教程(匯總)

    pnpm是 Node.js 的替代包管理器,它是 npm 的直接替代品,速度更快、效率更高,它由 npm/yarn 衍生而來,但卻解決了 npm/yarn 內(nèi)部潛在的 bug,并且極大了地優(yōu)化了性能,本文給大家介紹pnpm的安裝及其使用,感興趣的朋友一起看看吧
    2023-12-12
  • 使用Node操作MySQL的兩種方式

    使用Node操作MySQL的兩種方式

    本文將介紹如何在?Node.js?應(yīng)用中使用?mysql2?和?TypeORM?兩種方式操作?MySQL?數(shù)據(jù)庫,文中通過代碼示例介紹的非常詳細(xì),對大家的學(xué)習(xí)有一定的幫助,需要的朋友可以參考下
    2024-05-05
  • node.js 全局變量的具體使用

    node.js 全局變量的具體使用

    這篇文章主要介紹了node.js 全局變量的具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Node.js原生api搭建web服務(wù)器的方法步驟

    Node.js原生api搭建web服務(wù)器的方法步驟

    這篇文章主要介紹了Node.js原生api搭建web服務(wù)器的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • 如何用node優(yōu)雅地打印全鏈路日志

    如何用node優(yōu)雅地打印全鏈路日志

    這篇文章主要給大家介紹了關(guān)于如何用node優(yōu)雅地打印全鏈路日志的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-03-03
  • 基于Node實現(xiàn)可以操作MySQL的接口

    基于Node實現(xiàn)可以操作MySQL的接口

    這篇文章主要介紹了用Node寫個可以操作MySQL的接口,以前也用Node寫過接口,但不涉及數(shù)據(jù)庫操作,而我們發(fā)現(xiàn),后端寫接口,基本都繞不開數(shù)據(jù)庫操作,感覺不寫一個能操作數(shù)據(jù)庫的接口,就不算真正意義上學(xué)會了寫接口,那我們今天就學(xué)習(xí)一下,如何寫一個可以操作數(shù)據(jù)庫的接口
    2024-05-05
  • node.js中的buffer.toJSON方法使用說明

    node.js中的buffer.toJSON方法使用說明

    這篇文章主要介紹了node.js中的buffer.toJSON方法使用說明,本文介紹了buffer.toJSON的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12

最新評論

库伦旗| 开江县| 临夏市| 远安县| 舞钢市| 莱州市| 平利县| 隆尧县| 齐齐哈尔市| 尉氏县| 肇庆市| 庄河市| 古交市| 巴彦县| 济源市| 佛坪县| 乐至县| 景德镇市| 泗水县| 长顺县| 民和| 峨山| 南郑县| 子长县| 祁东县| 佛山市| 临泉县| 定兴县| 岑巩县| 临安市| 渭南市| 绥棱县| 福贡县| 通化市| 龙川县| 娄底市| 九江县| 文昌市| 山西省| 庐江县| 通城县|