当对大量结构化数据进行存储和访问时,就需要一个数据库来进行管理。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();