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插件写法笔记整理
Sep 06 Javascript
javascript框架设计读书笔记之模块加载系统
Dec 02 Javascript
jQuery实现指定区域外单击关闭指定层的方法【经典】
Jun 22 Javascript
使用vue.js制作分页组件
Jun 27 Javascript
js HTML5多图片上传及预览实例解析(不含前端的文件分割)
Aug 26 Javascript
jQuery表单验证简单示例
Oct 17 Javascript
浅谈js算法和流程控制
Dec 29 Javascript
Bootstrap 树控件使用经验分享(图文解说)
Nov 06 Javascript
jQuery基于闭包实现的显示与隐藏div功能示例
Jun 09 jQuery
angular 实现的输入框数字千分位及保留几位小数点功能示例
Jun 19 Javascript
vue v-model实现自定义样式多选与单选功能
Jul 05 Javascript
vue 解决setTimeOut和setInterval函数无效报错的问题
Jul 30 Javascript
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+MYSQL的文章管理系统(一)
2006/10/09 PHP
php实现文件下载更能介绍
2012/11/23 PHP
PHP性能分析工具xhprof的安装使用与注意事项
2017/12/19 PHP
windows环境下使用Composer安装ThinkPHP5
2018/05/18 PHP
详解PHP队列的实现
2019/03/14 PHP
PHP实现微信提现(企业付款到零钱)
2019/08/01 PHP
PHP实现数组根据某个字段进行水平合并,横向合并案例分析
2019/10/08 PHP
浅析JavaScript中的typeof运算符
2013/11/30 Javascript
Javascript基础教程之for循环
2015/01/18 Javascript
js正则表达式匹配数字字母下划线等
2015/04/14 Javascript
jQuery实现文件上传进度条特效
2015/08/12 Javascript
适用于javascript开发者的Processing.js入门教程
2016/02/24 Javascript
jQuery的实例及必知重要的jQuery选择器详解
2016/05/20 Javascript
微信小程序 PHP生成带参数二维码
2017/02/21 Javascript
node.js中debug模块的简单介绍与使用
2017/04/25 Javascript
node实现登录图片验证码的示例代码
2018/04/20 Javascript
微信小程序适配iphoneX的实现方法
2018/09/18 Javascript
vue中的inject学习教程
2019/04/24 Javascript
Vue快速实现通用表单验证功能
2019/12/05 Javascript
Vue proxyTable配置多个接口地址,解决跨域的问题
2020/09/11 Javascript
Vue和React有哪些区别
2020/09/12 Javascript
了不起的11个JavaScript代码重构最佳实践小结
2021/01/11 Javascript
python3实现暴力穷举博客园密码
2016/06/19 Python
利用Opencv中Houghline方法实现直线检测
2018/02/11 Python
TensorFlow搭建神经网络最佳实践
2018/03/09 Python
对Python3使运行暂停的方法详解
2019/02/18 Python
解决pycharm remote deployment 配置的问题
2019/06/27 Python
Python分析微信好友性别比例和省份城市分布比例的方法示例【基于itchat模块】
2020/05/29 Python
戴尔英国官网:Dell英国
2017/05/27 全球购物
澳大利亚儿童和婴儿产品在线商店:Lime Tree Kids
2017/10/05 全球购物
协议书模板
2014/04/23 职场文书
2014乡镇机关党员个人对照检查材料思想汇报
2014/10/09 职场文书
2015年安全生产月活动总结
2015/03/26 职场文书
读书笔记怎么写
2015/07/01 职场文书
2015年度考核个人工作总结
2015/10/24 职场文书
探讨Java中的深浅拷贝问题
2021/06/26 Java/Android