从零学习node.js之mysql数据库的操作(五)(2)

数据库连接池正是针对这个问题提出来的,它会负责分配、管理和释放数据库连接,允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个连接,释放空闲时间超过最大允许空闲时间的数据库连接以避免因为连接未释放而引起的数据库连接遗漏。

3.1 创建连接池

使用mysql.createPool()可创建连接池:

// test.js var mysql = require('mysql'); var pool = mysql.createPool({ host : '127.0.0.1', user : 'root', password : '123', database : 'test' }) pool.query('SELECT * FROM `user`', function(err, result){ if(err) throw err; console.log(result); pool.end(function(err){ if(err) throw err; console.log('connection ended'); }) });

getConnection()可以共享一个连接,或管理多个连接。

// test.js var mysql = require('mysql'); var pool = mysql.createPool({ host : '127.0.0.1', user : 'root', password : '123', database : 'test' }) pool.getConnection(function(err, connection){ if(err) throw err; connection.query('SELECT * FROM `user`', function(err, result){ if(err) throw err; console.log(result); }) });

连接使用完后通过调用connection.release()方法可以将连接返回到连接池中,这个连接可以被其它人重复使用:

pool.getConnection(function(err, connection){ if(err) throw err; connection.query('SELECT * FROM `user`', function(err, result){ if(err) throw err; console.log(result); connection.release(); // 接下来connection已经无法使用,它已经被返回到连接池中 }) });

可以使用connection.destroy()彻底销毁连接。

3.2 连接池事件

createPool()方法会返回一个连接池实例对象,这个对象中有一些事件。

connection

连接池中产生新连接时会发送'connection'事件:

pool.on('connection', function (connection) { console.log('new connection'); });

3.3 QUERY与GETCONNECTION的区别

这两个方法都能进行操作,那么这两者有什么区别呢?

在pool.getConnection中的connection在其回调函数里是一直的,可以保证这一系列的操作都是在同一个connection中执行的;pool.query则每次执行时可能会在不同的connection中执行,可能会得到意想不到的结果。

比如SQL_CALC_FOUND_ROWS和FOUND_ROWS这需要两个sql语句完成,是获取检索行的数目。

pool.query('SELECT SQL_CALC_FOUND_ROWS * FROM `user`'); pool.query('SELECT FOUND_ROWS()');

这两个可能在不同的connection中执行,第2个sql语句返回的就不是上一个sql语句的结果了。

四、sql防注入

sql防注入的关键就是不能直接把数据拼接到sql语句中,必须得对数据进行转义,或者使用提供的方法拼接sql语句。这里主要有四种方法可以使用。

4.1 使用ESCAPE()对参数进行编码

参数编码方法有:mysql.escape()/connection.escape()/pool.escape() ,这三个方法可以在你需要的时候调用:

var sql = 'SELECT * FROM `user` WHERE `uid`='+connection.escape('"123";//--'); console.log(sql); // SELECT * FROM `user` WHERE `uid`='\"123\";//--' connection.query(sql, function(err, result){ if(err) throw err; console.log(result); })

对双引号进行了安全转义。

escapeId()可以对不信任的表名,字段名进行转义。

var sql = 'SELECT * FROM '+connection.escapeId('user')+' WHERE `uid`=1'; connection.query(sql, function(err, result){ console.log(result); }) console.log(query.sql); // SELECT * FROM `user` WHERE `uid`=1

同时,escape()的编码规则如下:

Numbers不进行转换

Booleans转换为true/false

Date对象转换为'YYYY-mm-dd HH:ii:ss'字符串

Buffers转换为hex字符串,如X'0fa5'

Strings进行安全转义

Arrays转换为列表,如[‘a', ‘b']会转换为'a', ‘b'

多维数组转换为组列表,如[[‘a', ‘b'], [‘c', ‘d']]会转换为(‘a', ‘b'), (‘c', ‘d')

Objects会转换为key=value键值对的形式。嵌套的对象转换为字符串

undefined/null会转换为NULL

MySQL不支持NaN/Infinity,并且会触发MySQL错误

4.2 占位符

可以使用?作为参数占位符。在使用查询参数占位符时,在其内部自动调用 connection.escape() 方法对传入参数进行编码。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwzfgf.html