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 相关文章推荐
javascript之大字符串的连接的StringBuffer 类
May 08 Javascript
document.getElementById为空或不是对象的解决方法
Jan 24 Javascript
javascript小组件 原生table排序表格脚本(兼容ie firefox opera chrome)
Jul 25 Javascript
jquery ajax传递中文参数乱码问题及解决方法说明
Feb 07 Javascript
jquery鼠标放上去显示悬浮层即弹出定位的div层
Apr 25 Javascript
JS给Array添加是否包含字符串的简单方法
Oct 29 Javascript
利用js的闭包原理做对象封装及调用方法
Apr 07 Javascript
JavaScript实现鼠标滚轮控制页面图片切换功能示例
Oct 14 Javascript
ES6中Promise的使用方法实例总结
Feb 18 Javascript
如何在JavaScript中创建具有多个空格的字符串?
Feb 23 Javascript
ES11屡试不爽的新特性,你用上了几个
Oct 21 Javascript
解决vue init webpack 下载依赖卡住不动的问题
Nov 09 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下尝试使用GraphicsMagick的缩略图功能
2011/01/01 PHP
示例详解Laravel的注册重构
2016/08/14 PHP
PHP对象链式操作实现原理分析
2016/10/09 PHP
php 微信开发获取用户信息如何实现
2016/12/13 PHP
PHP十六进制颜色随机生成器功能示例
2017/07/24 PHP
php7 list()、session及其他模块的修改实例分析
2020/05/25 PHP
Javascript实现的分页函数
2006/12/22 Javascript
Jquery替换已存在于element上的event的方法
2010/03/09 Javascript
jquery 读取页面load get post ajax 四种方式代码写法
2011/04/02 Javascript
FF火狐下获取一个元素同类型的相邻元素实现代码
2012/12/15 Javascript
JavaScript中OnLoad几种使用方法
2012/12/15 Javascript
JavaScript对象和字串之间的转换实例探讨
2013/04/21 Javascript
JS代码判断IE6,IE7,IE8,IE9的函数代码
2013/08/02 Javascript
jquery操作复选框(checkbox)的12个小技巧总结
2014/02/04 Javascript
JS 打印界面的CSS居中代码适用所有浏览器
2014/03/19 Javascript
chrome不支持form.submit的解决方案
2015/04/28 Javascript
第一次接触神奇的Bootstrap基础排版
2016/07/26 Javascript
jQuery Validate格式验证功能实例代码(包括重名验证)
2017/07/18 jQuery
原生js实现省市区三级联动代码分享
2018/02/12 Javascript
node使用mysql获取数据库数据中文乱码问题的解决
2019/12/02 Javascript
[01:55]《走出家门看比赛》——DOTA2 2015国际邀请赛同城线下观战
2015/07/18 DOTA
Python编程把二叉树打印成多行代码
2018/01/04 Python
pandas DataFrame实现几列数据合并成为新的一列方法
2018/06/08 Python
python实现车牌识别的示例代码
2019/08/05 Python
在Python中预先初始化列表内容和长度的实现
2019/11/28 Python
Python利用myqr库创建自己的二维码
2020/11/24 Python
HTML5 CSS3给网站设计带来出色效果
2009/07/16 HTML / CSS
法国和欧洲海边和滑雪度假:Pierre & Vacances
2017/01/04 全球购物
巴西食品补充剂在线零售商:Músculos na Web
2017/08/07 全球购物
印尼美容产品购物网站:PerfectBeauty.id
2017/12/01 全球购物
化妆品促销方案
2014/02/24 职场文书
园艺师求职信
2014/04/27 职场文书
2014年自愿离婚协议书范本
2014/09/25 职场文书
幼儿园圣诞节活动总结
2015/05/06 职场文书
学会掌握自己命运的十条黄金法则:
2019/08/08 职场文书
vue route新窗口跳转页面并且携带与接收参数
2022/04/10 Vue.js