Node.js SQL数据库操作 (上)(操作MySQL数据库及 数据库连接池)

Posted YuLong~W

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js SQL数据库操作 (上)(操作MySQL数据库及 数据库连接池)相关的知识,希望对你有一定的参考价值。

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服务器返回的行
});

设置连接选项:

属性描述
host连接的数据库地址,默认为localhost
port连接地址对应的端口,默认3306
user用于连接的MySQL用户名
password用户的密码
database所需连接的数据库的名称(可选项)
charset连接的编码形式(默认为utf8_general_ci),决定整理排序规则
timezoneMySQL服务器上配置的时区(默认local)
dateStrings将强制日期类型(TIMESTAMP、DATETIME或DATE)作为字符串返回
connectTimeout设置连接时,返回失败前的未响应等待时间

终止连接:

  • 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,'2018-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模块及案例展示)

以上是关于Node.js SQL数据库操作 (上)(操作MySQL数据库及 数据库连接池)的主要内容,如果未能解决你的问题,请参考以下文章

Node.js SQL数据库操作 (下)(ORM框架Sequelize模块及案例展示)

在 node.js 中导入 sql 文件并针对 PostgreSQL 执行

在 Backand 如何从 node.js 操作上传文件?

Node.js学习11~基于Egg.js框架,对MySQL数据库实现增删改查操作

[转]在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查

Async.js解决Node.js操作MySQL的回调大坑