🌟前言
哈喽小伙伴们,新的专栏 Node 已开启;这个专栏里边会收录一些Node的基础知识和项目实战;今天我们带领大家初识一下 Node第三方包 mysql2 ;让我们一起来看看吧🤘
🌟访问数据库
如果要在Nodejs中去访问一个MySQL数据库,必须安装一个MySQL驱动,有了这个MySQL驱动才能跟MySQL数据库建立连接,然后执行各种各样的SQL语句。
🌟MySQL驱动
如果我们要访问数据库,必须得跟数据库建立一个网络连接,那么这个连接由谁来建立呢?
其实答案就是这个MySQL驱动,他会在底层跟数据库建立网络连接,有网络连接,接着才能去发送请求给数据库服务器!
因此,操作MySQL需要Nodejs版本的MySQL驱动,对于Java、PHP、Perl、.NET、Python、Ruby等各种常见的编程语言,MySQL都会提供对应语言的MySQL驱动,让各种语言编写的系统通过MySQL驱动去访问数据库。
🌟mysql2
mysql2是一个高性能的MySQL驱动程序。
为什么使用mysql2而不是经典的mysql库?主要基于以下原因:
更高的性能!
支持PreparedStatement,多次查询性能更高,书写SQL更简单;
自带Promise包装器,可以直接使用async/await语法;
绝大部分api和mysql库兼容,意味着mysql的文档和线上资料亦可作为参考。
PreparedStatement是预编译的,对于批量处理可以大大提高效率会。也就是说PreparedStatement先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率。
🌟安装
npm install --save mysql2
示例
const mysql = require('mysql2'); // 创建到数据库的连接 const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'root', database: 'test' }); // 简单查询 connection.query( 'SELECT * FROM `table` WHERE `name` = "Page" AND `age` > 45', function(err, results, fields) { console.log(results); // results contains rows returned by server console.log(fields); // fields contains extra meta data about results, if available } ); // 使用占位符 connection.query( 'SELECT * FROM `table` WHERE `name` = ? AND `age` > ?', ['Page', 45], function(err, results) { console.log(results); } );
🌟方法
🌟连接数据库
使用数据库之前,需要先连接数据库。语法格式:
mysql.createConnection(option)
其中 option 为连接数据库的配置项。如下为部分配置项:
我们使用语句创建一个连接:
const mysql = require('mysql2'); // 创建到数据库的连接 const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'root', database: 'test' });
🌟通过 query() 方法执行SQL语句
连接数据库之后,可以使用query()方法对数据库执行SQL操作。语法格式:
connection.query(sql,params,callback)
也可以通过组装SQL语句,可以用??代替表名、字段、索引名;用?代替数据。具体实例如下所示:
connection.query( 'SELECT * from xxx where id=?', [100], function (error, results, fields) { if (error) throw error; console.log('The solution is: ', results[0].solution); } );
🌟通过 execute() 方法执行SQL语句
execute()方法也是用于执行SQL语句
connection.execute( 'select * from admin where AdminID = ?', [2], function(err, results, fields) { if (err) { console.log('[SELECT ERROR] - ', err.message); return; } console.log(results); // console.log(fields); } )
execute()和query()之间的区别:
query是在node装SQL语句,而 execute 则是利用MySQL 的 PreparedStatement 机制来预编译SQL语句
execute 的优势是数据库原生支持的预编译机制,性能更高
query 的优势是更灵活,例如可以用??代替表名、字段、索引名;用?代替数据
🌟使用连接池
🌟连接池技术介绍
服务器可以快速创建和断开数据库连接,但对于高并发的后端服务器而言,数据库连接的频繁创建与断开,是非常重的负担。若在客户端与服务端交互前,可以事先创建若干连接并提前放置在连接池中,需要时可以从连接池直接获取,数据传输完成后,将连接归还至连接池中,从而减少频繁创建和释放连接所造成的开销。
连接池技术的核心思想是:连接复用,通过建立一个数据库连接池以及一套连接使用、分配、管理策略,使得该连接池中的连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。
在系统初始化时,根据相应的配置创建连接并放置在连接池中,以便需要使用时能从连接池中获取,这样就可以避免连接随意的建立、关闭造成的开销。
当客户请求数据库连接时,首先查看连接池中是否有空闲连接(指当前没有分配出去的连接)。如果存在空闲连接,则把连接分配给客户并作相应处理(即标记该连接为正在使用,引用计数加1)。如果没有空闲连接,则查看当前所开的连接数是不是已经达到maxConn(最大连接数),如果没达到就重新创建一个连接给请求的客户;如果达到就按设定的maxWaitTime(最大等待时间)进行等待,如果等待maxWaitTime后仍没有空闲连接,就抛出无空闲连接的异常给用户。
🌟mysql2连接池
具体的语法格式:
mysql.createPool()
其中的参数和createConnection()中的参数基本相同,但是多了几个对连接池的设定:
const pool = mysql.createPool({ host: 'localhost', user: 'root', database: 'test', password: "123456", waitForConnections: true, //连接超额是否等待 connectionLimit: 10, //一次创建的最大连接数 queueLimit: 0 //可以等待的连接的个数 });
在创建完连接池之后,可以使用和createConnection()连接相同的方式使用池(使用pool.query()和pool.execute()。也可以通过连接池手动获取连接进行数据库操作。
🌟使用 Promise
通过query()和execute()操作数据库时都是通过回调函数的形式获取放返回的数据。而我们可以使用Promise将异步转化为同步,以同步的方式来完成对数据库的操作。
在使用 Promise 时,分为两种方式:
通过 async\await 来实现
通过 promise() 函数来实现
在使用 Promise 时,需要require mysql2/promise:
const mysql = require('mysql2/promise');
🌟async\await操作数据库
通过async\await 和createConnection()的方式结合进行数据库操作
const mysql = require('mysql2/promise'); async function pro_createConnection() { let connection = await mysql.createConnection({ host: "localhost", user: "root", password: "123456", database: "student", multipleStatements: true }); let [results] = await connection.execute( 'select * from admin where AdminID = ?', [1] ) console.log(results); } pro_createConnection();
通过async\await 和createPool()的方式结合进行数据库操作
const mysql = require('mysql2/promise'); const pool = mysql.createPool({ host: "localhost", user: "root", password: "123456", database: "student", waitForConnections: true, //连接超额是否等待 connectionLimit: 10, //一次创建的最大连接数 queueLimit: 0 //可以等待的连接的个数 }); async function pro_createPool() { let [results] = await pool.execute( 'select * from admin where AdminID = ?', [1] ) console.log(results); } pro_createPool()
🌟promise()函数操作数据库
通过 promise() 函数和createConnection()的方式结合进行数据库操作
const mysql = require('mysql2'); let connection = mysql.createConnection({ host: "localhost", user: "root", password: "123456", database: "student", multipleStatements: true }); connection.promise().query('select * from admin where AdminID = ?', [1]) .then(([rows, fields]) => { console.log(rows); }) .catch(console.log) .then(() => connection.end());
通过 promise() 函数 和 createPool() 的方式结合进行数据库操作
const pool = mysql.createPool({ host: "localhost", user: "root", password: "123456", database: "student", waitForConnections: true, //连接超额是否等待 connectionLimit: 10, //一次创建的最大连接数 queueLimit: 0 //可以等待的连接的个数 }); pool.promise().query('select * from admin where AdminID = ?', [1]) .then(([rows, fields]) => { console.log(rows); }) .catch(console.log)
在使用 Promise 完成数据库操作时,除了上述实例中需要添加的部分,其余部分,如创建连接和连接池,query() 和 execute() 等的使用方法不变。
🌟写在最后
更多Node知识以及API请大家持续关注,尽请期待。各位小伙伴让我们 let’s be prepared at all times!