Node.js數(shù)據(jù)庫操作之連接MySQL數(shù)據(jù)庫(一)
介紹
首先說來介紹一下MySQL(非廣告)。MySQL是由瑞典的MySQL AB公司開發(fā),后來被甲骨文公司收購(gòu)。和Oracle一樣,MySQL是一個(gè)典型的關(guān)系型數(shù)據(jù)庫,在百度百科中,把MySQL稱為是最好的關(guān)系數(shù)據(jù)庫管理系統(tǒng)的之一。
什么是關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫
說到關(guān)系型數(shù)據(jù)庫,大家肯定就會(huì)想到另一個(gè)詞與之對(duì)應(yīng),非關(guān)系型數(shù)據(jù)庫,那么這兩者有什么樣的區(qū)別呢?
關(guān)系型數(shù)據(jù)庫是指采用了關(guān)系模型(指的是二維表格模型)來組織數(shù)據(jù)的數(shù)據(jù)庫,有穩(wěn)定的表結(jié)構(gòu);而非關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)沒有關(guān)系模型,以對(duì)象的形式存放到數(shù)據(jù)庫中,對(duì)象之間的關(guān)系是通過每個(gè)對(duì)象的屬性來決定的,有點(diǎn)類似于一長(zhǎng)串json對(duì)象。典型的非關(guān)系型數(shù)據(jù)庫有MongoDB和Redis。
MySQL的優(yōu)缺點(diǎn)
我在項(xiàng)目中使用MySQL作為數(shù)據(jù)庫主要是因?yàn)樗w積小,速度快,安裝完才幾百兆,相比于Oracle好幾個(gè)G它確實(shí)“輕”了不少。而且核心程序采用多線程編程,線程也是輕量級(jí)的進(jìn)程,不會(huì)占用太多的系統(tǒng)資源,因此一般的中小型網(wǎng)站都選擇MySQL數(shù)據(jù)庫,而且最重要的是MySQL幾乎是免費(fèi)的。
但是也正是由于它的輕量級(jí),因此它也“砍掉”了一些功能,比如存儲(chǔ)過程等。
使用
這邊不再贅述MySQL的安裝過程,有需要的讀者可以自行百度安裝教程。在我們的項(xiàng)目中通過npm install mysql --save
來安裝依賴。
一個(gè)簡(jiǎn)單的Demo
首先,通過一個(gè)小的Demo來測(cè)試我們的環(huán)境是否已經(jīng)搭建完畢了:
var mysql = require('mysql'); // 連接數(shù)據(jù)庫的配置 var connection = mysql.createConnection({ // 主機(jī)名稱,一般是本機(jī) host: 'localhost', // 數(shù)據(jù)庫的端口號(hào),如果不設(shè)置,默認(rèn)是3306 port: 3306 // 創(chuàng)建數(shù)據(jù)庫時(shí)設(shè)置用戶名 user: 'xyf', // 創(chuàng)建數(shù)據(jù)庫時(shí)設(shè)置的密碼 password: 'xyf', // 創(chuàng)建的數(shù)據(jù)庫 database: 'xyf_db' }); // 與數(shù)據(jù)庫建立連接 connection.connect(); // 查詢數(shù)據(jù)庫 connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) { if (err) throw err; console.log('The solution is: ', rows[0].solution); }); // 關(guān)閉連接 connection.end();
運(yùn)行程序,如果顯示“The solution is: 2”,那么整個(gè)連接查詢是成功的;如果不成功,讀者可以根據(jù)打印的錯(cuò)誤信息提示來修改。
在查詢完數(shù)據(jù)庫后,需要通過end()
函數(shù)將連接關(guān)閉。如果連接一直打開,首先會(huì)浪費(fèi)不必要的系統(tǒng)資源;其次,數(shù)據(jù)庫的連接數(shù)量有限制,如果達(dá)到上限時(shí),會(huì)出現(xiàn)后續(xù)連接不上報(bào)錯(cuò)的情況。
建立數(shù)據(jù)庫連接
要想查詢數(shù)據(jù)庫,首先就要跟數(shù)據(jù)庫建立連接,上面的Demo給出了一種建立連接的方式。官方文檔還給出了另外兩種建立連接的方式。
隱式建立連接
var mysql = require('mysql'); var connection = mysql.createConnection(...); 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();
我們并沒有像Demo中一樣使用connect()
函數(shù)建立連接,而且直接進(jìn)行了查詢,這時(shí)候建立連接將會(huì)被隱式地調(diào)用。
連接回調(diào)查詢
上面兩種連接方式并沒有對(duì)連接出錯(cuò)的情況進(jìn)行處理,一旦連接出現(xiàn)錯(cuò)誤將帶來連鎖的多米諾骨牌效應(yīng),查詢也將會(huì)失敗,整個(gè)程序也會(huì)崩潰,為了避免出現(xiàn)這樣的情況,我們將查詢和關(guān)閉連接放到回調(diào)函數(shù)中。
var mysql = require('mysql'); var connection = mysql.createConnection(...); connection.connect(function(err){ if(err){ // 連接失敗時(shí)的錯(cuò)誤處理 console.log(err); return; } connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) { if(err){ // 查詢失敗時(shí)的錯(cuò)誤處理 console.log(err); return err; } console.log('The solution is: ', rows[0].solution); }); connection.end(); });
注:上面的三種建立連接的方式都是可以的,取決于筆者怎么處理連接錯(cuò)誤。
關(guān)閉連接
打開了數(shù)據(jù)庫的連接我們也需要關(guān)閉連接,有兩種關(guān)閉連接的方式,一種就是我們上面用的end()
方法來關(guān)閉連接,它可以接收一個(gè)回調(diào)函數(shù)。
connection.end(function(err) { // 這時(shí)連接已經(jīng)被關(guān)閉了 });
通過end()函數(shù)關(guān)閉連接不會(huì)影響隊(duì)列中的查詢。還有一種方式是調(diào)用destroy()
函數(shù)。
connection.destroy();
destroy()
函數(shù)確保了沒有更多的時(shí)間和回調(diào)會(huì)觸發(fā)連接。同時(shí)destroy()
函數(shù)也沒有回調(diào)函數(shù)。
使用數(shù)據(jù)庫連接池
數(shù)據(jù)庫連接是一種關(guān)鍵的、有限的、昂貴的資源。 —百度百科
通過上面的數(shù)據(jù)庫連接方式我們會(huì)發(fā)現(xiàn)直接創(chuàng)建一個(gè)數(shù)據(jù)庫連接比較“危險(xiǎn)”,因?yàn)橛泻芏喾N可能性導(dǎo)致連接的失敗。而且如果我們的程序中隨意都可以和數(shù)據(jù)庫建立連接的話,我們的程序就比較得混亂,不能很有效的管理數(shù)據(jù)庫連接。mysql庫提供了另一種數(shù)據(jù)庫連接方式給我們。
什么是數(shù)據(jù)庫連接池
數(shù)據(jù)庫連接池負(fù)責(zé)分配、管理和釋放數(shù)據(jù)庫連接,它允許應(yīng)用程序重復(fù)使用一個(gè)現(xiàn)有的數(shù)據(jù)庫連接,而不是再重新建立一個(gè)。這項(xiàng)技術(shù)能明顯提高對(duì)數(shù)據(jù)庫操作的性能。
用一個(gè)很生動(dòng)的例子來形容數(shù)據(jù)庫連接池的工作:以前我們存取錢都需要去銀行的柜臺(tái)交易,銀行的柜臺(tái)數(shù)量是有限的,人多的時(shí)候還需要排隊(duì);現(xiàn)在我們把錢都存在了支付寶上,每次需要用錢的時(shí)候都直接跟支付寶“要”,不需要再跑到銀行去了,所有和銀行“打交道”的業(yè)務(wù)都交給了支付寶幫我們來管理。
數(shù)據(jù)庫連接池在初始化的時(shí)候?qū)⒁欢〝?shù)量(數(shù)量受最小連接數(shù)制約)的數(shù)據(jù)庫連接存放到數(shù)據(jù)庫連接池中,不管這些數(shù)據(jù)庫連接是否被使用,連接池一直要存放這么多的連接數(shù)量。連接池的最大數(shù)據(jù)庫連接數(shù)量限制了連接池最多能同時(shí)擁有的連接數(shù),如果超過最大連接數(shù)時(shí),請(qǐng)求將會(huì)被添加到等待隊(duì)列中去。
創(chuàng)建連接池
下面就開始創(chuàng)建一個(gè)數(shù)據(jù)庫連接池。
var mysql = require('mysql'); var pool=mysql.createPool({ host: 'localhost', user: 'xyf', password: 'xyf', port: '3306', database: 'xyf_db', // 最大連接數(shù),默認(rèn)為10 connectionLimit: 10, }) pool.getConnection(function(err,connection){ if(err){ console.log(err); return; } connection.query('SELECT 1 + 1 AS solution',function(err,result){ connection.release(); if(err){ console.log(err); return; } console.log('The solution is: ', result[0].solution); }) })
首先我們通過createPool()
方法創(chuàng)建了一個(gè)數(shù)據(jù)庫連接池,它的配置參數(shù)和上面的配置基本差不多,只是多了一個(gè)最大連接數(shù)。每次我們需要和數(shù)據(jù)庫建立連接的時(shí)候不再是直接建立連接,而是去連接池中通過pool.getConnection()
方法“撈取”已有的連接。這個(gè)方法有一個(gè)回調(diào),數(shù)據(jù)庫連接作為回調(diào)參數(shù)返回給我們使用。
每次查詢完數(shù)據(jù)庫是都要使用release()
方法釋放數(shù)據(jù)庫連接,這樣數(shù)據(jù)庫連接又回到了連接池中。釋放后如果再使用connection將會(huì)報(bào)錯(cuò)。
關(guān)閉連接池
一般數(shù)據(jù)庫連接池不需要關(guān)閉,但是如果使用完連接池需要將所有的連接關(guān)閉,我們可以使用pool.end()
方法將其關(guān)閉。
pool.end(function (err) { // 所有連接池中的數(shù)據(jù)庫連接將會(huì)被關(guān)閉 });
end()
方法提供一個(gè)回調(diào)方法,以便在所有連接關(guān)閉時(shí)進(jìn)行一些操作。關(guān)閉連接池前所有隊(duì)列中的查詢?nèi)稳粫?huì)執(zhí)行完成,所以每次關(guān)閉的時(shí)間都不一樣。一旦end()方法被調(diào)用了,getConnection和其他一些獲取連接池中連接的方法不會(huì)再被執(zhí)行。
總結(jié)
本篇文章主要學(xué)習(xí)了nodejs連接mysql數(shù)據(jù)庫的一些兩種連接方式,直接連接和通過數(shù)據(jù)庫連接池的方式進(jìn)行連接。直接創(chuàng)建連接的方式比較“危險(xiǎn)”,推薦使用連接池,把所有的連接集中管理,既方便又安全。
相關(guān)文章
Nodejs實(shí)現(xiàn)爬蟲抓取數(shù)據(jù)實(shí)例解析
這篇文章主要介紹了Nodejs實(shí)現(xiàn)爬蟲抓取數(shù)據(jù)實(shí)例解析,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-07-07node基于puppeteer模擬登錄抓取頁面的實(shí)現(xiàn)
本篇文章主要介紹了node基于puppeteer模擬登錄抓取頁面的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05node.js實(shí)現(xiàn)pdf與圖片互轉(zhuǎn)代碼示例
因工作需求,記錄一次如何在Node中pdf與圖片互轉(zhuǎn)各種操作,這篇文章主要給大家介紹了關(guān)于node.js實(shí)現(xiàn)pdf與圖片互轉(zhuǎn)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-04-04node.js基于express使用websocket的方法
這篇文章主要介紹了node.js基于express使用websocket的方法,結(jié)合實(shí)例形式分析了node.js基于express調(diào)用websocket相關(guān)設(shè)置與使用操作技巧,需要的朋友可以參考下2017-11-11Node.js連接postgreSQL并進(jìn)行數(shù)據(jù)操作
自從MySQL被Oracle收購(gòu)以后,PostgreSQL逐漸成為開源關(guān)系型數(shù)據(jù)庫的首選。這篇文章就給大家介紹了關(guān)于Node.js如何連接postgreSQL數(shù)據(jù)庫,并進(jìn)行數(shù)據(jù)操作的方法,有需要的朋友們可以參考借鑒,下面來一起看看吧。2016-12-12