Nodejs使用mysql2操作數(shù)據(jù)庫(kù)的方法完整講解
mysql2 相比于 mysql 的優(yōu)勢(shì)
mysql2 是一個(gè)基于 Node.js 的 MySQL 客戶端庫(kù),相比于 mysql 庫(kù),它具有以下幾個(gè)優(yōu)勢(shì):
性能更好:mysql2 庫(kù)在性能方面進(jìn)行了優(yōu)化,使用了更高效的底層實(shí)現(xiàn)。它使用了更快的連接池管理和查詢執(zhí)行機(jī)制,可以處理更高的并發(fā)請(qǐng)求,提供更好的性能表現(xiàn)。
支持 Promise 和 async/await:mysql2 庫(kù)原生支持 Promise 和 async/await,使得編寫異步代碼更加方便和直觀。您可以使用
promise().query()
方法執(zhí)行查詢,并使用await
關(guān)鍵字等待查詢結(jié)果。支持流式查詢:mysql2 庫(kù)支持流式查詢,可以通過(guò)創(chuàng)建可讀流來(lái)處理大型查詢結(jié)果集。這對(duì)于處理大量數(shù)據(jù)或需要逐行處理結(jié)果的情況非常有用,可以減少內(nèi)存占用并提高性能。
更好的錯(cuò)誤處理:mysql2 庫(kù)提供了更好的錯(cuò)誤處理機(jī)制,可以更詳細(xì)地捕獲和處理數(shù)據(jù)庫(kù)操作中的錯(cuò)誤。它返回的錯(cuò)誤對(duì)象包含更多有用的信息,如 SQL 語(yǔ)句、錯(cuò)誤代碼和錯(cuò)誤堆棧等,有助于更好地調(diào)試和排查問(wèn)題。
支持預(yù)處理語(yǔ)句:mysql2 庫(kù)支持預(yù)處理語(yǔ)句,可以使用占位符來(lái)安全地構(gòu)建和執(zhí)行 SQL 查詢。這可以防止 SQL 注入攻擊,并提高應(yīng)用程序的安全性。
安裝
npm install mysql2
連接數(shù)據(jù)庫(kù)
要使用 mysql2 連接到 MySQL 數(shù)據(jù)庫(kù),您需要安裝 mysql2 包,并使用適當(dāng)?shù)倪B接參數(shù)來(lái)創(chuàng)建連接。以下是一個(gè)示例,展示了如何使用 mysql2 連接到 MySQL 數(shù)據(jù)庫(kù):
const mysql = require("mysql2"); // 創(chuàng)建數(shù)據(jù)庫(kù)連接 const connection = mysql.createConnection({ host: "localhost", // 主機(jī)地址 user: "root", // 用戶名 password: "password", // 密碼 port: 3306, // 端口號(hào),默認(rèn)為 3306 database: "mydatabase", // 數(shù)據(jù)庫(kù)名稱 charset: "UTF8_GENERAL_CI", // 連接字符集,默認(rèn)為 UTF8_GENERAL_CI connectTimeout: 10000, // 連接超時(shí)時(shí)間,單位為毫秒 multipleStatements: false // 是否允許一個(gè) query 中有多個(gè) MySQL 語(yǔ)句,默認(rèn)為 false }); // 連接到數(shù)據(jù)庫(kù) connection.connect((err) => { if (err) { console.error("Error connecting to database:", err); return; } console.log("Connected to database"); // 在這里執(zhí)行數(shù)據(jù)庫(kù)操作 }); // 在數(shù)據(jù)庫(kù)連接關(guān)閉時(shí)觸發(fā) connection.on("end", () => { console.log("Database connection closed"); }); // 在發(fā)生錯(cuò)誤時(shí)觸發(fā) connection.on("error", (err) => { console.error("Database error:", err); }); // 關(guān)閉數(shù)據(jù)庫(kù)連接 connection.end();
在這個(gè)示例中,我們使用 mysql.createConnection()
方法創(chuàng)建了一個(gè)數(shù)據(jù)庫(kù)連接,并傳遞了連接參數(shù)(主機(jī)名、用戶名、密碼和數(shù)據(jù)庫(kù)名稱)。然后,我們使用 connection.connect()
方法來(lái)連接到數(shù)據(jù)庫(kù)。
在連接成功后,您可以在回調(diào)函數(shù)中執(zhí)行數(shù)據(jù)庫(kù)操作。在這個(gè)示例中,我們只是簡(jiǎn)單地輸出連接成功的消息,但您可以在這里執(zhí)行任何數(shù)據(jù)庫(kù)操作,如查詢、插入、更新等。
請(qǐng)注意,為了確保數(shù)據(jù)庫(kù)連接的正確關(guān)閉,我們監(jiān)聽了 end
事件,并在事件處理程序中關(guān)閉了連接。此外,我們還監(jiān)聽了 error
事件,以處理可能發(fā)生的數(shù)據(jù)庫(kù)錯(cuò)誤。
最后,我們使用 connection.end()
方法來(lái)關(guān)閉數(shù)據(jù)庫(kù)連接。
請(qǐng)根據(jù)您的實(shí)際情況修改連接參數(shù),以適應(yīng)您的 MySQL 數(shù)據(jù)庫(kù)的配置。
通過(guò) query() 方法執(zhí)行SQL語(yǔ)句
連接數(shù)據(jù)庫(kù)之后,可以使用query()
方法對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改查操作。
具體的語(yǔ)法格式:connection.query(sql,params,callback)
,以下是對(duì) query()
方法的參數(shù)進(jìn)行詳細(xì)說(shuō)明:
sql
:要執(zhí)行的 SQL 查詢語(yǔ)句,可以是 SELECT、INSERT、UPDATE、DELETE 等。params
(可選):一個(gè)數(shù)組,包含要傳遞給 SQL 查詢的參數(shù)。這些參數(shù)可以用于預(yù)處理語(yǔ)句中的占位符。callback
:一個(gè)回調(diào)函數(shù),用于處理查詢結(jié)果或錯(cuò)誤?;卣{(diào)函數(shù)接收兩個(gè)參數(shù):err
和results
。err
是一個(gè)錯(cuò)誤對(duì)象(如果有錯(cuò)誤發(fā)生),results
是查詢結(jié)果。
以下是一個(gè)示例,展示了如何使用 query()
方法執(zhí)行 SQL 查詢并處理結(jié)果:
const mysql = require("mysql2"); // 創(chuàng)建數(shù)據(jù)庫(kù)連接 const connection = mysql.createConnection({ host: "localhost", user: "root", password: "password", database: "mydatabase" }); // 連接到數(shù)據(jù)庫(kù) connection.connect((err) => { if (err) { console.error("Error connecting to database:", err); return; } console.log("Connected to database"); // 執(zhí)行 SQL 查詢,可以用??代替表名、字段、索引名;用?代替數(shù)據(jù)。 const sql = "SELECT * FROM users WHERE age > ?"; const params = [18]; connection.query(sql, params, (err, results) => { if (err) { console.error("Error executing query:", err); return; } console.log("Query results:", results); }); }); // 在數(shù)據(jù)庫(kù)連接關(guān)閉時(shí)觸發(fā) connection.on("end", () => { console.log("Database connection closed"); }); // 在發(fā)生錯(cuò)誤時(shí)觸發(fā) connection.on("error", (err) => { console.error("Database error:", err); }); // 關(guān)閉數(shù)據(jù)庫(kù)連接 connection.end();
在這個(gè)示例中,我們執(zhí)行了一個(gè) SELECT 查詢,查找年齡大于 18 的用戶。我們使用了預(yù)處理語(yǔ)句,并將參數(shù) [18]
傳遞給 query()
方法。
在回調(diào)函數(shù)中,我們處理了查詢結(jié)果或錯(cuò)誤。如果查詢成功,我們打印出查詢結(jié)果 results
。
請(qǐng)根據(jù)您的實(shí)際需求修改 SQL 查詢語(yǔ)句、參數(shù)和處理邏輯。您可以執(zhí)行任何有效的 SQL 查詢,并根據(jù)需要處理查詢結(jié)果或錯(cuò)誤。
通過(guò) execute() 方法執(zhí)行SQL語(yǔ)句
以下是一個(gè)使用mysql2模塊執(zhí)行SQL查詢的示例:
const mysql = require('mysql2'); // 創(chuàng)建數(shù)據(jù)庫(kù)連接 const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'password', database: 'mydatabase' }); // 執(zhí)行SQL查詢 connection.execute( 'SELECT * FROM users WHERE age > ?', [18], function(err, results, fields) { if (err) { console.log('[SELECT ERROR] - ', err.message); return; } console.log(results); // console.log(fields); } ); // 關(guān)閉數(shù)據(jù)庫(kù)連接 connection.end();
在這個(gè)例子中,我們創(chuàng)建了一個(gè)名為mydatabase
的數(shù)據(jù)庫(kù)連接,并執(zhí)行了一個(gè)查詢語(yǔ)句,查找年齡大于18歲的用戶。如果查詢成功,結(jié)果將會(huì)在控制臺(tái)打印出來(lái)。你可以取消注釋掉console.log(fields)
這行代碼來(lái)查看字段信息。
請(qǐng)確保將localhost
、root
、password
和mydatabase
替換為你自己的數(shù)據(jù)庫(kù)連接信息。
execute()和query()之間的區(qū)別:
下面是execute()
和query()
之間的區(qū)別:
- 參數(shù)化查詢:
execute()
方法支持參數(shù)化查詢,可以使用占位符(例如?
)來(lái)代替查詢中的參數(shù),而query()
方法不支持參數(shù)化查詢,需要通過(guò)字符串拼接來(lái)傳遞參數(shù)。 - 回調(diào)函數(shù):
execute()
和query()
方法都接受一個(gè)回調(diào)函數(shù)作為參數(shù),用于處理查詢結(jié)果。但是,execute()
方法的回調(diào)函數(shù)有三個(gè)參數(shù)(err, results, fields
),分別表示錯(cuò)誤信息、查詢結(jié)果和字段信息;而query()
方法的回調(diào)函數(shù)有兩個(gè)參數(shù)(err, results
),只表示錯(cuò)誤信息和查詢結(jié)果。 - 錯(cuò)誤處理:在
execute()
方法中,需要手動(dòng)處理錯(cuò)誤,通過(guò)判斷err
參數(shù)是否存在來(lái)確定是否有錯(cuò)誤發(fā)生。而query()
方法會(huì)自動(dòng)處理錯(cuò)誤,如果發(fā)生錯(cuò)誤,會(huì)將錯(cuò)誤信息傳遞給回調(diào)函數(shù)的err
參數(shù)。 - 返回結(jié)果:無(wú)論是
execute()
還是query()
方法,都會(huì)返回一個(gè)結(jié)果集對(duì)象。但是,execute()
方法返回的結(jié)果集對(duì)象中包含更多的信息,如受影響的行數(shù)等。 - 預(yù)編譯:
execute()
方法支持預(yù)編譯,可以提前編譯SQL語(yǔ)句,以提高執(zhí)行效率。而query()
方法不支持預(yù)編譯。
連接池
通過(guò)重新使用以前的連接,連接池可以保持打開狀態(tài),從而減少連接到MySQL服務(wù)器的時(shí)間。在Node.js中,可以使用mysql.createPool()
方法來(lái)創(chuàng)建連接池。它的語(yǔ)法格式如下:
const mysql = require('mysql2'); // 創(chuàng)建連接池 const pool = mysql.createPool({ host: 'localhost', user: 'root', password: 'password', database: 'mydatabase', connectionLimit: 10, // 最大連接數(shù) queueLimit: 0, // 排隊(duì)等待連接的最大請(qǐng)求數(shù),0表示無(wú)限制 waitForConnections: true // 當(dāng)連接池達(dá)到最大連接數(shù)時(shí),是否等待可用連接 });
使用連接池進(jìn)行數(shù)據(jù)庫(kù)操作可以使用pool.query()
和pool.execute()
方法,也可以手動(dòng)獲取連接進(jìn)行操作。下面是使用連接池進(jìn)行數(shù)據(jù)庫(kù)操作的示例代碼:
使用pool.query()方法:
const mysql = require('mysql2'); // 創(chuàng)建連接池 const pool = mysql.createPool({ host: 'localhost', user: 'root', password: 'password', database: 'mydatabase', connectionLimit: 10 }); // 使用pool.query()方法執(zhí)行查詢 pool.query('SELECT * FROM users', function(err, results, fields) { if (err) { console.log('[QUERY ERROR] - ', err.message); return; } console.log(results); }); // 關(guān)閉連接池 pool.end();
使用pool.execute()方法:
const mysql = require('mysql2'); // 創(chuàng)建連接池 const pool = mysql.createPool({ host: 'localhost', user: 'root', password: 'password', database: 'mydatabase', connectionLimit: 10 }); // 使用pool.execute()方法執(zhí)行查詢 pool.execute('SELECT * FROM users', function(err, results, fields) { if (err) { console.log('[EXECUTE ERROR] - ', err.message); return; } console.log(results); }); // 關(guān)閉連接池 pool.end();
手動(dòng)獲取連接進(jìn)行數(shù)據(jù)庫(kù)操作:
const mysql = require('mysql2'); // 創(chuàng)建連接池 const pool = mysql.createPool({ host: 'localhost', user: 'root', password: 'password', database: 'mydatabase', connectionLimit: 10 }); // 從連接池中獲取連接 pool.getConnection(function(err, connection) { if (err) { console.log('[CONNECTION ERROR] - ', err.message); return; } // 執(zhí)行查詢操作 connection.query('SELECT * FROM users', function(err, results, fields) { connection.release(); // 釋放連接回連接池 if (err) { console.log('[QUERY ERROR] - ', err.message); return; } console.log(results); }); }); // 關(guān)閉連接池 pool.end();
使用 Promise
在之前通過(guò)query()和execute()操作數(shù)據(jù)庫(kù)時(shí)都是通過(guò)回調(diào)函數(shù)的形式獲取放返回的數(shù)據(jù)。而我們可以使用Promise將異步轉(zhuǎn)化為同步使用Promise來(lái)實(shí)現(xiàn)異步操作可以通過(guò)async/await和promise()函數(shù)兩種方式。
- 一種是通過(guò) async\await 來(lái)實(shí)現(xiàn),
- 種是通過(guò) promise() 函數(shù)來(lái)實(shí)現(xiàn)。
下面是使用async/await和createConnection()、createPool()的方式創(chuàng)建數(shù)據(jù)庫(kù)操作的示例代碼:
使用async/await和createConnection()的方式:
const mysql = require('mysql2'); // 創(chuàng)建連接 const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'password', database: 'mydatabase' }); // 封裝查詢函數(shù) function query(sql) { return new Promise((resolve, reject) => { connection.query(sql, function(err, results, fields) { if (err) { reject(err); } else { resolve(results); } }); }); } // 使用async/await進(jìn)行數(shù)據(jù)庫(kù)操作 async function fetchData() { try { const results = await query('SELECT * FROM users'); console.log(results); } catch (err) { console.log('[QUERY ERROR] - ', err.message); } finally { connection.end(); } } fetchData();
使用async/await和createPool()的方式:
const mysql = require('mysql2'); // 創(chuàng)建連接池 const pool = mysql.createPool({ host: 'localhost', user: 'root', password: 'password', database: 'mydatabase', connectionLimit: 10 }); // 封裝查詢函數(shù) function query(sql) { return new Promise((resolve, reject) => { pool.query(sql, function(err, results, fields) { if (err) { reject(err); } else { resolve(results); } }); }); } // 使用async/await進(jìn)行數(shù)據(jù)庫(kù)操作 async function fetchData() { let connection; try { connection = await pool.promise().getConnection(); const results = await connection.query('SELECT * FROM users'); console.log(results); } catch (err) { console.log('[QUERY ERROR] - ', err.message); } finally { if (connection) { connection.release(); } pool.end(); } } fetchData();
使用promise()函數(shù)和createConnection()的方式:
const mysql = require('mysql2'); // 創(chuàng)建連接 const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'password', database: 'mydatabase' }); // 封裝查詢函數(shù) function query(sql) { return new Promise((resolve, reject) => { connection.query(sql, function(err, results, fields) { if (err) { reject(err); } else { resolve(results); } }); }); } // 使用promise()函數(shù)進(jìn)行數(shù)據(jù)庫(kù)操作 query('SELECT * FROM users') .then(results => { console.log(results); }) .catch(err => { console.log('[QUERY ERROR] - ', err.message); }) .finally(() => { connection.end(); });
無(wú)論是使用async/await還是promise()函數(shù),都可以將異步操作轉(zhuǎn)化為同步的方式來(lái)完成對(duì)數(shù)據(jù)庫(kù)的操作。根據(jù)個(gè)人的喜好和項(xiàng)目需求,選擇適合的方式來(lái)使用Promise。
總結(jié)
到此這篇關(guān)于Nodejs使用mysql2操作數(shù)據(jù)庫(kù)的文章就介紹到這了,更多相關(guān)Nodejs用mysql2操作數(shù)據(jù)庫(kù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
node 使用multer中間件上傳報(bào)錯(cuò)Unexpected end of fo
再前幾天還是可以正常上傳,但今天運(yùn)行出現(xiàn)該報(bào)錯(cuò),下面通過(guò)場(chǎng)景分析給大家介紹node使用multer中間件上傳,報(bào)錯(cuò)Unexpected end of form的解決方案,感興趣的朋友一起看看吧2025-03-03node.js中的querystring.parse方法使用說(shuō)明
這篇文章主要介紹了node.js中的querystring.parse方法使用說(shuō)明,本文介紹了querystring.parse的方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12Linux系統(tǒng)中利用node.js提取Word(doc/docx)及PDF文本的內(nèi)容
這篇文章主要給大家介紹了關(guān)于Linux系統(tǒng)中利用node.js提取Word(doc/docx)及PDF文本的內(nèi)容,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面跟著小編來(lái)一起看看吧。2017-06-06Node.js API詳解之 string_decoder用法實(shí)例分析
這篇文章主要介紹了Node.js API詳解之 string_decoder用法,結(jié)合實(shí)例形式分析了Node.js API中string_decoder的功能、用法及操作注意事項(xiàng),需要的朋友可以參考下2020-04-04淺談NodeJs之?dāng)?shù)據(jù)庫(kù)異常處理
這篇文章主要介紹了淺談NodeJs之?dāng)?shù)據(jù)庫(kù)異常處理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10詳解Node.js中exports和module.exports的區(qū)別
這篇文章主要介紹了詳解Node.js中exports和module.exports的區(qū)別,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04node命令行工具之實(shí)現(xiàn)項(xiàng)目工程自動(dòng)初始化的標(biāo)準(zhǔn)流程
這篇文章主要介紹了node命令行工具之實(shí)現(xiàn)項(xiàng)目工程自動(dòng)初始化的標(biāo)準(zhǔn)流程 ,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08