文章目录
Node.js MySQL驱动操作 MySQL 数据库连接 MySQL 数据库增删改查操作防止 SQL 注入攻击数据库连接池操作Node.js MySQL驱动
Node.js的原生MySQL驱动库名为mysql
MySQL2项目是原生MySQL驱动项目的升级版本,兼容mysql并支持其主要特性,提供新的特性:
更快更好的性能预处理语句对编码和排序规则的扩展支持Promise包装器SSL与认证开关自定义流
安装MySQL2 驱动(库名称为mysql2 ):npm install mysql2
操作 MySQL 数据库
连接 MySQL 数据库
1、显式建立连接示例:
const mysql = require('mysql2');//创建到数据库的连接const connection = mysql.createConnection({host: 'localhost',user: 'root',password : 'abc123',database: 'testmydb'});connection.connect(function(err) {if (err) {console.error('连接错误: ' + err.stack);return;}console.log('连接ID:' + connection.threadId);});
2、隐式建立连接示例:
var mysql = require('mysql2');var connection = mysql.createConnection(...);//此处省略连接选项代码connection.query('SELECT * FROM `bookinfo`',function(err, results) {console.log(results); // 结果包括由MySQL服务器返回的行});
设置连接选项:
终止连接:
connection.end(function(err) { // 连接终止 }) ;
connection.destroy();
增删改查操作
1、查询记录:
第1种形式:.query(sqlString, callback)
const mysql = require('mysql2');//建立连接const connection = mysql.createConnection({host: 'localhost',user: 'root',password : 'abc123',database: 'testmydb'});connection.connect();//执行查询操作connection.query('SELECT * FROM `bookinfo` WHERE `press` = "人民邮电出版社"', function (err, results, fields) {if (err) throw err;console.log('-------查询记录----------');console.log('查询结果:',results); console.log('查询结果字段:',fields); });connection.end(); //终止连接
第2种形式:.query(sqlString, values, callback)
connection.query('SELECT * FROM `bookinfo` WHERE `press` = ?', ['人民邮电出版社'],function (err, results, fields) {});
第3种形式:.query(options, callback)
connection.query({'SELECT * FROM `bookinfo` WHERE `press` = ?',timeout: 40000, // 40秒values: ['人民邮电出版社']}, function (error, results, fields) {});
第2、3种结合:
connection.query({'SELECT * FROM `bookinfo` WHERE `press` = ?',timeout: 40000, // 40s},['人民邮电出版社'],function (err, results, fields) {);
只有单个占位符的查询:
connection.query('SELECT * FROM `bookinfo` WHERE `press` = ?', '人民邮电出版社',function (err, results, fields) {});
2、增加记录:
//此处省略建立连接代码//定义增加记录的SQL语句和参数var addSql = ' INSERT INTO `bookinfo`(`isbn`, `name`, `author`, `press`, `price`, `pubdate`) VALUES(?,?,?,?,?,?)';var addSql_Params = ['9787115488435', '人工智能(第2版)','史蒂芬•卢奇','人民邮电出版社',108.00,'-09-01'];//通过查询命令执行增加操作connection.query(addSql,addSql_Params,function (err, results) {if (err) throw err;console.log('-------插入记录----------');console.log('插入记录的ID:',results.insertId);console.log('插入结果:',results); });connection.end();
3、修改记录:
//此处省略建立连接代码//定义修改记录的SQL语句和参数var updateSql = 'UPDATE bookinfo SET author = ?,price = ? WHERE id = ?';var updateSql_Params = ['[日]结城浩',87.5,9];//通过查询命令执行修改操作connection.query(updateSql,updateSql_Params,function (err, result) {if (err) throw err;console.log('-------修改记录----------');console.log('修改所影响的行数:',result.affectedRows); console.log('修改所改变的行数:',result.changedRows); });connection.end();
4、删除记录:
//此处省略建立连接代码//定义删除记录的SQL语句var delSql = 'DELETE FROM bookinfo WHERE id = 11';//通过查询命令执行删除操作connection.query(delSql,function (err, result) {if (err) throw err;console.log('-------删除记录----------');console.log('删除的行数:',result.affectedRows); });connection.end();
防止 SQL 注入攻击
1、转义可以通过mysql.escape( )、connection.escape( )或pool.escape( )方法来实现。
var userId = 'some user provided value';var sql = 'SELECT * FROM users WHERE id = ' + connection.escape(userId);connection.query(sql, function(err, results) {// ...});
2、可以将符号?
作为查询字符串中的占位符以替代要转义的值。
connection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) {// ...});
流式查询:
var query = connection.query('SELECT * FROM posts');query.on('error', function(err) {//处理错误,这之后会触发 'end' 事件}).on('fields', function(fields) {// 处理字段数据}).on('result', function(row) {connection.pause();//如果处理过程涉及到I/O操作,暂停连接会很有用processRow(row, function() {connection.resume();});}).on('end', function() {//所有行都已经接收完毕});
使用预处理语句:
connection.execute('SELECT * FROM 'table' WHERE 'name' = ? AND 'age' > ?',['Rick C-137', 53],function(err, results, fields) {console.log(results); });
数据库连接池操作
在开发web应用程序时,连接池是一个很重要的概念。建立一个数据库连接所消耗的性能成本是很高的。在服务器应用程序中,如果为每一个接收到的客户端请求都建立一个或多个数据库连接,将严重降低应用程序性能。
在服务器应用程序中通常需要为多个数据库连接创建并维护一个连接池,当连接不再需要时,这些连接可以缓存在连接池中,当接收到下一个客户端请求时,从连接池中取出连接并重新利用,而不需要再重新建立连接
数据库对象和数据库连接池的使用方法对比:
1.创建数据库连接对象:
//导入mysql模块const mysql = require('mysql2');//创建数据库连接对象const connection = mysql.createConnection({host : 'localhost',port : 3306,user : 'root',password : '123',database : 'school'})
2.将数据保存到数据库的方法:
function save(params) {connection.query('insert into student set?',{s_id:params.id,s_name:params.name,s_birthday:params.birthday,s_gender:params.gender},(err,result) => {if (err){console.log(err);return;}console.log('插入数据成功');console.log(result);//断开数据库连接connection.end();})}
1.创建数据库连接池:
//导入mysql模块const mysql = require('mysql2');//创建数据库连接池const pool=mysql.createPool({connectionLimit:20,host : 'localhost',port : 3306,user : 'root',password : '123',database : 'school',multipleStatements:true //是否允许一个query中有多个MySQL语句 (默认:false)});
2.将数据保存到数据库连接池方法:
function save(params) {pool.getConnection((err, connection) => {if (err) {console.log('连接数据库失败', err);return;}connection.query('insert into student set?', {s_id: params.id,s_name: params.name,s_birthday: params.birthday,s_gender: params.gender}, (err, result) => {if (err) {console.log(err);return;}console.log('插入数据成功');//释放数据库连接对象connection.release();})})}
学习文章:Node.js SQL数据库操作 (下)(ORM框架、Sequelize模块及案例展示)