当对大量结构化数据进行存储和访问时,就需要一个数据库来进行管理。MySQL是一个关系型数据,它会以结构化的方式存储和获取数据。在Node.js中,可以使用node-mysql模块实现与MySQL的通信。
1. 安装与连接
node-mysql是一个MySql驱动,在安装这个模块前请确保已在本机安装MySql或有一个在其它主机上可访问的MySql实例。
1.1 安装
确认有一个可访问的数据库后,可以使用以下命令安装:
npm install mysql
1.2 连接MySql
模块安装后,就可以使用这个模块连接并与MySql进行通信。
下面是一个连接MySql示例:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'secret',
database : 'my_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();
在上面示例中,使用createConnection()方法创建MySql访问对象,通过这个对象我们可连接数据库,及进行一些数据库相关操作。将以上代码保存为myConn.js,运行效果如下:
$ node myConn.js The solution is: 2
2. 数据读取
2.1 两种读取方式
建立查询后,可以在查询方法query的回调函数中读取查询结果:
var query = connection.query('SELECT * from users', function(err, rows, fields) {
if (err) throw err;
console.log(rows);
});
在这个查询中,查询方法的回调函数中会包含所有查询结果。如果数据量比较大,查询效率会降低,这时我们可以结合查询对象的事件机制进行处理。
当使用query方法进行查询,会返回一个Query对象,在这个对象中会有error、field、result、end事件。结合这些事件可以实现高效的数据读取:
var query = connection.query('SELECT * from users')
query.on('result', function(row){
console.log('读取到一行数据:%s', row);
})
2.2 查询占位符
在实际使用中,查询时往往需要传入一些查询参数。下面是一个不好的使用查询参数的示例:
var input = '1';
connection.query('SELECT * FROM test WHERE id>'+input);
在这个示例中存在SQL注入的风险,如果用户向下面这样传入参数时你的数据就可能会被删除:
// 用户传入的参数
var input = '1; DELETE FROM test WHERE id=1';
connection.query('SELECT * FROM test WHERE id>'+input);
解决这一问题,可以使用查询占位符。在node-mysql中使用?号表示要传入的参数,而实际参数以数组的形式传入:
connection.query('SELECT * FROM test WHERE id>?', [input]);
这样,虽然这个语句没有按我们预期的效果执行,但确有效阻止了SQL注入的风险。
3. 完整操作
在对数据进行操作时,会涉及数据库操作、表操作、表数据操作。接下来我们将编写一个完完整的MySql操作示例,在这个示例中我们会进行数据库、表、表中数据的操作:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '111111'
});
connection.on('error', function(err){
throw err;
})
connection.connect();
connection.query('DROP DATABASE IF EXISTS node');
// 创建数据库
connection.query('CREATE DATABASE node');
connection.query('use node');
//创建表
connection.query('CREATE TABLE test(id INT(11) AUTO_INCREMENT, contect varchar(255), PRIMARY KEY(id)) charset=utf8');
// 插入一些数据
for(var i=0; i<10; i++){
connection.query('INSERT INTO test(contect) VALUES (?)', ['插入数据'+(i)]);
}
// 数据更新
connection.query('UPDATE test SET contect=? WHERE id>? ', ['new contect', 8]);
// 查询修改后的数据
var query = connection.query('SELECT * FROM test WHERE id>? AND id', [1, 5]);
query.on('error', function(err){
throw err;
})
query.on('result', function(row){
console.log('读取到一行数据:%s', row)
})
query.on('end', function(result){
console.log('数据读取完成')
})
connection.end();
