Node.js数据库操作之连接MySQL数据库(一)


Posted in Javascript onMarch 04, 2017

介绍

首先说来介绍一下MySQL(非广告)。MySQL是由瑞典的MySQL AB公司开发,后来被甲骨文公司收购。和Oracle一样,MySQL是一个典型的关系型数据库,在百度百科中,把MySQL称为是最好的关系数据库管理系统的之一。

什么是关系型数据库和非关系型数据库

说到关系型数据库,大家肯定就会想到另一个词与之对应,非关系型数据库,那么这两者有什么样的区别呢?

关系型数据库是指采用了关系模型(指的是二维表格模型)来组织数据的数据库,有稳定的表结构;而非关系型数据库中的数据没有关系模型,以对象的形式存放到数据库中,对象之间的关系是通过每个对象的属性来决定的,有点类似于一长串json对象。典型的非关系型数据库有MongoDB和Redis。

MySQL的优缺点

我在项目中使用MySQL作为数据库主要是因为它体积小,速度快,安装完才几百兆,相比于Oracle好几个G它确实“轻”了不少。而且核心程序采用多线程编程,线程也是轻量级的进程,不会占用太多的系统资源,因此一般的中小型网站都选择MySQL数据库,而且最重要的是MySQL几乎是免费的。

但是也正是由于它的轻量级,因此它也“砍掉”了一些功能,比如存储过程等。

使用

这边不再赘述MySQL的安装过程,有需要的读者可以自行百度安装教程。在我们的项目中通过npm install mysql --save来安装依赖。

一个简单的Demo

首先,通过一个小的Demo来测试我们的环境是否已经搭建完毕了:

var mysql = require('mysql');
// 连接数据库的配置
var connection = mysql.createConnection({
 // 主机名称,一般是本机
 host: 'localhost',
 // 数据库的端口号,如果不设置,默认是3306
 port: 3306
 // 创建数据库时设置用户名
 user: 'xyf',
 // 创建数据库时设置的密码
 password: 'xyf',
 // 创建的数据库
 database: 'xyf_db'
});
// 与数据库建立连接
connection.connect();
// 查询数据库
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();

运行程序,如果显示“The solution is: 2”,那么整个连接查询是成功的;如果不成功,读者可以根据打印的错误信息提示来修改。

在查询完数据库后,需要通过end()函数将连接关闭。如果连接一直打开,首先会浪费不必要的系统资源;其次,数据库的连接数量有限制,如果达到上限时,会出现后续连接不上报错的情况。

建立数据库连接

要想查询数据库,首先就要跟数据库建立连接,上面的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()函数建立连接,而且直接进行了查询,这时候建立连接将会被隐式地调用。

连接回调查询

上面两种连接方式并没有对连接出错的情况进行处理,一旦连接出现错误将带来连锁的多米诺骨牌效应,查询也将会失败,整个程序也会崩溃,为了避免出现这样的情况,我们将查询和关闭连接放到回调函数中。

var mysql = require('mysql');
var connection = mysql.createConnection(...);
connection.connect(function(err){
 if(err){
 // 连接失败时的错误处理
 console.log(err);
 return;
 } 
 connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
 if(err){
 // 查询失败时的错误处理
 console.log(err);
 return err;
 }
 console.log('The solution is: ', rows[0].solution);
 });
 connection.end();
});

注:上面的三种建立连接的方式都是可以的,取决于笔者怎么处理连接错误。

关闭连接

打开了数据库的连接我们也需要关闭连接,有两种关闭连接的方式,一种就是我们上面用的end()方法来关闭连接,它可以接收一个回调函数。

connection.end(function(err) {
 // 这时连接已经被关闭了
});

通过end()函数关闭连接不会影响队列中的查询。还有一种方式是调用destroy()函数。

connection.destroy();

destroy()函数确保了没有更多的时间和回调会触发连接。同时destroy()函数也没有回调函数。

使用数据库连接池

数据库连接是一种关键的、有限的、昂贵的资源。 —百度百科

通过上面的数据库连接方式我们会发现直接创建一个数据库连接比较“危险”,因为有很多种可能性导致连接的失败。而且如果我们的程序中随意都可以和数据库建立连接的话,我们的程序就比较得混乱,不能很有效的管理数据库连接。mysql库提供了另一种数据库连接方式给我们。

什么是数据库连接池

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。这项技术能明显提高对数据库操作的性能。

用一个很生动的例子来形容数据库连接池的工作:以前我们存取钱都需要去银行的柜台交易,银行的柜台数量是有限的,人多的时候还需要排队;现在我们把钱都存在了支付宝上,每次需要用钱的时候都直接跟支付宝“要”,不需要再跑到银行去了,所有和银行“打交道”的业务都交给了支付宝帮我们来管理。

Node.js数据库操作之连接MySQL数据库(一)

数据库连接池在初始化的时候将一定数量(数量受最小连接数制约)的数据库连接存放到数据库连接池中,不管这些数据库连接是否被使用,连接池一直要存放这么多的连接数量。连接池的最大数据库连接数量限制了连接池最多能同时拥有的连接数,如果超过最大连接数时,请求将会被添加到等待队列中去。

创建连接池

下面就开始创建一个数据库连接池。

var mysql = require('mysql');
var pool=mysql.createPool({
 host: 'localhost',
 user: 'xyf',
 password: 'xyf',
 port: '3306',
 database: 'xyf_db',
 // 最大连接数,默认为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()方法创建了一个数据库连接池,它的配置参数和上面的配置基本差不多,只是多了一个最大连接数。每次我们需要和数据库建立连接的时候不再是直接建立连接,而是去连接池中通过pool.getConnection()方法“捞取”已有的连接。这个方法有一个回调,数据库连接作为回调参数返回给我们使用。

每次查询完数据库是都要使用release()方法释放数据库连接,这样数据库连接又回到了连接池中。释放后如果再使用connection将会报错。

关闭连接池

一般数据库连接池不需要关闭,但是如果使用完连接池需要将所有的连接关闭,我们可以使用pool.end()方法将其关闭。

pool.end(function (err) {
 // 所有连接池中的数据库连接将会被关闭
});

end()方法提供一个回调方法,以便在所有连接关闭时进行一些操作。关闭连接池前所有队列中的查询任然会执行完成,所以每次关闭的时间都不一样。一旦end()方法被调用了,getConnection和其他一些获取连接池中连接的方法不会再被执行。

总结

本篇文章主要学习了nodejs连接mysql数据库的一些两种连接方式,直接连接和通过数据库连接池的方式进行连接。直接创建连接的方式比较“危险”,推荐使用连接池,把所有的连接集中管理,既方便又安全。

Javascript 相关文章推荐
jQuery中height()方法用法实例
Dec 24 Javascript
jquery分隔Url的param方法(推荐)
May 25 Javascript
关于数据与后端进行交流匹配(点亮星星)
Aug 03 Javascript
window.open不被拦截的简单实现代码(推荐)
Aug 04 Javascript
bootstrap中的 form表单属性role="form"的作用详解
Jan 20 Javascript
js实现多行文本框统计剩余字数功能
Mar 28 Javascript
Layui table 组件的使用之初始化加载数据、数据刷新表格、传参数
Sep 11 Javascript
jQuery使用动画队列自定义动画操作示例
Jun 16 jQuery
Vue结合后台导入导出Excel问题详解
Feb 19 Javascript
VsCode与Node.js知识点详解
Sep 05 Javascript
一篇文章带你浅入webpack的DLL优化打包
Feb 20 Javascript
Vue实现指令式动态追加小球动画组件的步骤
Dec 18 Vue.js
jQuery实现贪吃蛇小游戏(附源码下载)
Mar 04 #Javascript
详解vue父子模版嵌套案例
Mar 04 #Javascript
vue指令以及dom操作详解
Mar 04 #Javascript
JS如何判断浏览器类型和详细区分IE各版本浏览器
Mar 04 #Javascript
详解在Vue中通过自定义指令获取dom元素
Mar 04 #Javascript
在javaScript中检测数据类型的几种方式小结
Mar 04 #Javascript
jQuery插件echarts实现的去掉X轴、Y轴和网格线效果示例【附demo源码下载】
Mar 04 #Javascript
You might like
php懒人函数 自动添加数据
2011/06/28 PHP
php批量上传的实现代码
2013/06/09 PHP
关于PhpStorm设置点击编辑文件自动定位源文件的实现方式
2020/12/30 PHP
运用Windows XP附带的Msicuu.exe、Msizap.exe来彻底卸载顽固程序
2007/04/21 Javascript
Javascript解决常见浏览器兼容问题的12种方法
2010/01/04 Javascript
jQuery EasyUI API 中文文档 - ValidateBox验证框
2011/10/06 Javascript
jquery实现excel导出的方法
2013/04/04 Javascript
jquery foreach使用示例
2013/09/12 Javascript
JavaScript数值转换的三种方式总结
2014/07/31 Javascript
javascript实现页面刷新时自动清空表单并选中的方法
2015/07/18 Javascript
jQuery使用serialize()表单序列化时出现中文乱码问题的解决办法
2016/07/27 Javascript
JavaScript toUpperCase()方法使用详解
2016/08/26 Javascript
详解Vue微信公众号开发踩坑全记录
2017/08/21 Javascript
jQuery ajax读取本地json文件的实例
2017/10/31 jQuery
vue.js学习笔记之v-bind和v-on解析
2018/05/03 Javascript
JS实现统计字符串中字符出现个数及最大个数功能示例
2018/06/04 Javascript
JavaScript设计模式之原型模式分析【ES5与ES6】
2018/07/26 Javascript
Nodejs异步流程框架async的方法
2019/06/07 NodeJs
JS中的算法与数据结构之队列(Queue)实例详解
2019/08/20 Javascript
[02:42]完美大师赛主赛事淘汰赛第三日观众采访
2017/11/25 DOTA
Python 学习笔记
2008/12/27 Python
Python中第三方库Requests库的高级用法详解
2017/03/12 Python
Python符号计算之实现函数极限的方法
2019/07/15 Python
CSS实现的一闪而过的图片闪光效果
2014/04/23 HTML / CSS
html5 css3实例教程 一款html5和css3实现的小机器人走路动画
2014/10/20 HTML / CSS
西班牙自行车和跑步商店:Alltricks
2018/07/07 全球购物
eBay英国购物网站:eBay.co.uk
2019/06/19 全球购物
eBay意大利购物网站:eBay.it
2019/09/04 全球购物
美国宠物护理专家:Revival Animal Health
2020/01/05 全球购物
如果有两个类A,B,怎么样才能使A在发生一个事件的时候通知B
2016/03/12 面试题
酒店个人培训自我鉴定
2013/12/11 职场文书
语文高效课堂实施方案
2014/05/03 职场文书
2014年安全员工作总结
2014/11/13 职场文书
期末个人总结范文
2015/02/13 职场文书
奖励申请报告范文
2015/05/15 职场文书
Python进程池与进程锁之语法学习
2022/04/11 Python