Node.js使用MySql驅(qū)動(dòng)進(jìn)行持久化實(shí)例

前提:已安裝MySql Server
內(nèi)容:使用Node.js的MySQL驅(qū)動(dòng)來(lái)實(shí)現(xiàn)Node.js持久化

安裝


下載mysql依賴:

npm i mysql –S

導(dǎo)入mysql模塊

const mysql = require('mysql')

介紹


Node.js的MySQL驅(qū)動(dòng)由JS編寫,不需要編譯,MIT開(kāi)源。使用方法非常簡(jiǎn)單。
Node.js的mysql驅(qū)動(dòng)地址:
https://github.com/mysqljs/mysql
官方的例子如下:

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'me',
  password : 'secret',
  database : 'my_db'
});

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

connection.end();

通過(guò)以上例子,我們知道了使用Node.js的原生MySQL驅(qū)動(dòng)主要通過(guò)以下方法:

  • mysql.createConnection(cfg):創(chuàng)建連接對(duì)象,傳入連接配置
    連接配置:
    連接配置是一個(gè)對(duì)象,包含的項(xiàng)如下:
    • host: 連接數(shù)據(jù)庫(kù)所在的主機(jī)名. (默認(rèn): localhost)
    • port: 連接端口. (默認(rèn): 3306)
    • localAddress: 用于TCP連接的IP地址. (可選)
    • socketPath: 鏈接到unix域的路徑。在使用host和port時(shí)該參數(shù)會(huì)被忽略.
    • user: MySQL用戶的用戶名.
    • password: MySQL用戶的密碼.
    • database: 鏈接到的數(shù)據(jù)庫(kù)名稱 (可選).
    • charset: 連接的字符集. (默認(rèn): 'UTF8_GENERAL_CI'.設(shè)置該值要使用大寫!)
    • timezone: 儲(chǔ)存本地時(shí)間的時(shí)區(qū). (默認(rèn): 'local')
    • stringifyObjects: 是否序列化對(duì)象. See issue #501. (默認(rèn): 'false')
    • insecureAuth: 是否允許舊的身份驗(yàn)證方法連接到數(shù)據(jù)庫(kù)實(shí)例. (默認(rèn): false)
    • typeCast: 確定是否講column值轉(zhuǎn)換為本地JavaScript類型列值. (默認(rèn): true)
    • queryFormat: 自定義的查詢語(yǔ)句格式化函數(shù).
    • supportBigNumbers: 數(shù)據(jù)庫(kù)處理大數(shù)字(長(zhǎng)整型和含小數(shù)),時(shí)應(yīng)該啟用 (默認(rèn): false).
    • bigNumberStrings: 啟用 supportBigNumbers和bigNumberStrings 并強(qiáng)制這些數(shù)字以字符串的方式返回(默認(rèn): false).
    • dateStrings: 強(qiáng)制日期類型(TIMESTAMP, DATETIME, DATE)以字符串返回,而不是一javascript Date對(duì)象返回. (默認(rèn): false)
    • debug: 是否開(kāi)啟調(diào)試. (默認(rèn): false)
    • multipleStatements: 是否允許在一個(gè)query中傳遞多個(gè)查詢語(yǔ)句. (Default: false)
    • flags: 鏈接標(biāo)志.
      你也可以直接使用一個(gè)字符串來(lái)連接數(shù)據(jù)庫(kù)
var connection = mysql.createConnection('mysql://user:pass@host/db?debug=true&charset=BIG5_CHINESE_CI&timezone=-0700');
  • connection.connect() : 連接數(shù)據(jù)庫(kù)
  • connection.query(sql,(err,result)=>{}):查詢語(yǔ)句,此驅(qū)動(dòng)所有sql語(yǔ)句都通過(guò)query語(yǔ)句執(zhí)行
  • connection.end():關(guān)閉連接,在關(guān)閉連接時(shí)需要確認(rèn)所有的query語(yǔ)句都執(zhí)行完畢。需要放在順序執(zhí)行的最后。如果query出錯(cuò),仍然會(huì)終止連接,錯(cuò)誤會(huì)傳遞到回調(diào)函數(shù)中處理。還要一個(gè)connection.destroy()方法的作用也是結(jié)束數(shù)據(jù)庫(kù)連接,與end方法不同的是,destroy方法會(huì)立即終止連接,即使還有query方法還沒(méi)有完成,也不會(huì)觸發(fā)回調(diào)函數(shù)。
    每個(gè)使用在連接對(duì)象上的方法都是同步的,順序執(zhí)行的。意味著此驅(qū)動(dòng)沒(méi)有提供異步的想promise的方法。

實(shí)例步驟1、連接數(shù)據(jù)庫(kù)


新建mysql.js文件,安裝并引入mysql模塊,設(shè)置用戶密碼等連接數(shù)據(jù)庫(kù):

const mysql = require('mysql')
//連接配置
const cfg = {
    host:'localhost',
    user:'root',//默認(rèn)root用戶
    password:'admin',
    database:'test',
}
//創(chuàng)建連接對(duì)象
const conn = mysql.createConnection(cfg);

//連接數(shù)據(jù)庫(kù)
conn.connect(err =>{
    if(err){
        throw err
    }
    console.log("連接成功")
})

運(yùn)行文件:

nodemon .\mysql

nodemon可自動(dòng)監(jiān)測(cè)node.js文件變化

運(yùn)行結(jié)果

也可以通過(guò)查詢語(yǔ)句來(lái)連接數(shù)據(jù)庫(kù)


const mysql = require('mysql')
//連接配置
const cfg = {
    host:'localhost',
    user:'root',//默認(rèn)root用戶
    password:'admin',
    database:'test',
}
//創(chuàng)建連接對(duì)象
const conn = mysql.createConnection(cfg);
//連接并執(zhí)行sql
conn.query('SELECT 1', function (error, results, fields) {
  if (error) throw error;
  console.log("連接成功")
});

執(zhí)行結(jié)果:


執(zhí)行結(jié)果

實(shí)例步驟2、使用連接池


mysql驅(qū)動(dòng)提供了連接池來(lái)提高查詢和操作效率。
實(shí)例如下:

var pool  = mysql.createPool({
    connectionLimit : 10,
    host:'localhost',
    user:'root',//默認(rèn)root用戶
    password:'admin',
    database:'test',
  });
  
  pool.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
    if (error) throw error;
    console.log("連接成功")
    console.log('The solution is: ', results[0].solution);
  });

執(zhí)行結(jié)果:


執(zhí)行結(jié)果

通過(guò)以上實(shí)例,使用連接池的方法如下:

  • mysql.createPool(cfg):傳入連接配置,這個(gè)方法是pool.getConnection() -> connection.query() -> connection.release()的一個(gè)簡(jiǎn)單版本,connection.release()釋放鏈接到連接池。如果需要關(guān)閉連接并且刪除,需要使用connection.destroy()
    pool除了接受和connection相同的參數(shù)外,還接受幾個(gè)擴(kuò)展的參數(shù)
    • createConnection: 用于創(chuàng)建鏈接的函數(shù). (Default: mysql.createConnection)
    • waitForConnections: 決定當(dāng)沒(méi)有連接池或者鏈接數(shù)打到最大值時(shí)pool的行為. 為true時(shí)鏈接會(huì)被放入隊(duì)列中在可用是調(diào)用,為false時(shí)會(huì)立即返回error. (Default: true)
    • connectionLimit: 最大連接數(shù). (Default: 10)
    • queueLimit: 連接池中連接請(qǐng)求的烈的最大長(zhǎng)度,超過(guò)這個(gè)長(zhǎng)度就會(huì)報(bào)錯(cuò),值為0時(shí)沒(méi)有限制. (Default: 0)

實(shí)例步驟3、使用query


通過(guò)上述我們知道query方法是mysql驅(qū)動(dòng)進(jìn)行sql語(yǔ)句執(zhí)行的唯一方法,創(chuàng)建幾個(gè)sql語(yǔ)句并執(zhí)行如下:


const mysql = require('mysql')
//連接配置
const cfg = {
    host:'localhost',
    user:'root',//默認(rèn)root用戶
    password:'admin',
    database:'test',
}
//創(chuàng)建連接對(duì)象
const conn = mysql.createConnection(cfg);
//sql語(yǔ)句
const CREATE_SQL = `CREATE TABLE IF NOT EXISTS test (
    id INT NOT NULL AUTO_INCREMENT,
    message VARCHAR(45) NULL,
    PRIMARY KEY (id))`;
const INSERT_SQL = `INSERT INTO test(message) VALUES(?)`;
const SELECT_SQL = `SELECT * FROM test`;
//連接數(shù)據(jù)庫(kù)
conn.connect(err =>{
    if(err){
        throw err
    }
    console.log("連接成功")
    //創(chuàng)建表
    conn.query(CREATE_SQL,(err) =>{
        //插入數(shù)據(jù)
        //格式化sql語(yǔ)句并輸出
        const sql = mysql.format(INSERT_SQL,'hello');
        console.log(sql);
        conn.query(INSERT_SQL,'hello',(err,result)=>{
            console.log(result);
            conn.query(SELECT_SQL,(err,results)=>{
                console.log(results);
                //不使用連接池時(shí)需要關(guān)閉
                conn.end();
            })
        })
    })
})

運(yùn)行如下:


執(zhí)行結(jié)果

我們知道m(xù)ysql驅(qū)動(dòng)是不提供promise方法的,如果我們想使用,我們可以自己封裝一個(gè)query方法:

//封裝
function query(conn,sql,param=null){
    return new Promise((resolve,reject)=>{
        conn.query(sql,param,(err,results)=>{
            if(err){
                reject(err)
            }else{
                resolve(results)
            }
        })
    })
}

使用方法如下:

query(conn,SELECT_SQL).then(results=>{
        console.log(results)
    }).catch(err=>{
        console.log(err)
    })
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容