在node中操作mysql小记
学习到需要接触数据库的时候,开始使用的是通过mongoose操作的mongodb,而且并没有配置本地的mongodb,而是用的云端托管的mongolab,作为一个小白,简单的mongoose操作还行,不求甚解式的去储存数据读取数据,但为什么要这样做,以及除了这样做还能怎样做,我便一无所知。想来想去,我决定先还是把mongodb放一放,先仔细了解下mysql再说,毕竟手上有一本sql必知必会。
这本书当然不错,讲得很详细,但那只是操作mysql的sql语句,我想了解下node中是如何操作mysql,或者说在node中如何与mysql等数据库关联的?在node.js连接mysql的过程,我们通常有两种连接方法,普通连接和连接池。我这里只有对普通连接的小结:
下边是我的一些小结:
1、安装mysql组件:
npm install mysql
2、在node中运行第一个mysql查询:
var mysql = require('mysql');
var connection = mysql.createConnection({
(
host: 'localhost',
user: 'root',
password: 'your password',
database: 'usersdata'
)
});
connection.connect();
var queryString = '在这里输入你要使用的sql语句';
connection.query(queryString,function(err,rows,fields) {
if(err) {
throw err;
}
//在这里输入你要进行的操作
});
connection.end();
注意:除此之外,你还可以将连接选项(connection options)作为一个单一的字符串而不是一个对象插入进去。
执行查询
最简单的执行查询操作就是调用connection或pool对象的实例的.query( )方法。调用.query()方法可以有三种不同的形式,下面是最简单的一种:
connection.query('mysql查询字符串',function(err,results,fields) {
//执行操作
});
注意:query()方法的第二个参数是一个回调函数,它的三个参数分别代表着不同的含义:
- 在查找过程中,如果出错返回的Error
- results包含查找的结果
- fields包含返回结果的字段信息
connection对象的query方法需要一个回调函数,当回调函数中的三个参数任意一个结束后,该函数会被执行,在上例子中回调函数为一名函数function()。
上面的代码中定义了一个会将结果作为一个单一的数据流返回的匿名函数。但是,如果table有数量非常多的rows,同时你想当每个row但会时对其单独处理,而不是等待着去搜集所有的rows,你可以将上面的代码改成如下这样:
var mysql = require('mysql');
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'your password',
database: 'usersdata'
});
connection.connect();
var query = connection.query('在这里输入你的sql操作语句');
query.on('error',function(err) {
throw err;
});
query.on('fields',function(fields) {
console.log(fields);
});
query.on('result',function(row) {
console.log(row.user_name);
});
connection.end();
注意:上面的代码中每当有一行数据返回时将其写入console。如果因为某些原因你需要在每一行数据返回前去处理他们,你不得不去暂停query,当你的那些操作完成后再去回复它。
query.on('result',function(row) {
connection.pause();
//你可以在这里进行一些操作
console.log(row);
connection.resume();
});
对query的值进行隐码
为了避免sql的隐码攻击,你可以运行quey之前,对用户数据进行隐藏。下面有两种方法,第一种使用?操作符:
var mysql = require('mysql');
var connection = mysql.createConnection({
//略
});
var key = '_edit_lock';
var queryString = 'SELECT * FROM usersdata WHERE meta_key = ?';
connection.query(queryString,[key],function(err,rows,fields) {
if(err) {
throw err;
}
for(var i in rows) {
console.log(rows[i]);
}
});
connection.end();
另外一种方式是使用 connection.escape( )方法:
var mysql = require('mysql');
var connection = mysql.createConnection({
//略
});
var key = '_edit_lock';
var queryString = 'SELECT * FROM usersdata WHERE meta_key = ' + connection.escape(key);
connection.query(queryString,function(err,rows,fields) {
if(err) {
throw err;
}
for(var i in rows) {
console.log(rows[i]);
}
});
获得插入行的id
如果你向表格中插入了一个有自动递增的主键的行的话,你可以通过下面的写法来重新获得这个插入行的id:
connection.query('INSERT INTO posts SET ?',{title:'test'},function(err,result) {
if(err) {
throw err;
}
console.log(result.insertId);
})
获取affected rows的数量
当进行查询过程中,会在数据库中对相应的行进行遍历查找,通过以下的方法可以在插入、更新、删除语句中获得受影响的行数:
connection.query('DELETE FORM posts WHERE title = "wrong"',function(err,result) {
if(err) {
throw err;
}
console.log('deleted' + result.affectedRows + 'rows');
});
获取被改变行的数量
通过result.changedRows这个属性来获得:
changedRows 不同于 affectedRows的点在于它不包括更新行的数量,因为更新行的值并没有被改变。
connection.query('UPDATE posts SET...',function(err,result) {
if(err) {
throw err;
}
console.log('changed' + result.changedRows + 'rows');
});
其他的一些小方法:
- 获得连接的id:通过connection.threadId来获得给定连接的id。
(未完待续,等我实际用到哪些地方的时候再填上)
中断连接
通过指令来关闭连接的方法有两种:
1、 调用connection的end()方法:
connection.end(function(err) {
//
});
2、调用destroy()方法:
connection.destroy(function(err) {
//
});
后者会对潜在的套接(underlying socket)造成立即的终止,且会确保在这之后不会有任何的事件或函数为连接而触发。
中断重连
mysql的连接可能因为一个错误意外的关闭,此外你可以通过相应的指令来明确的关闭连接。如果你的关闭是因为一些错误意外造成的话,那么你需要去解决这个错误,如果需要请重新打开它;
重连connection的本质实际上是重新建立一个连接。连接一旦断开,从设计角度讲师不能被真正的重新连接的。
connection.on('close',function(err) {
if(err) {
//连接意外中断,重新连接
connection = mysql.createConnection(connection.config();
} else {
console.log('conneciton closed normally')
}
});
注意: connection.config 对象保存着最近的链接信息,你可以通过它重新连接到mysql服务器。尝试着将 connection.config 添加到console.log()中,会返回以下信息:
{
host: 'localhost',
port: 3306,
socketPath: undefined,
user: 'sam',
password: 'some-pass',
database: 'usersdata',
insecureAuth: false,
debug: undefined,
typeCast: true,
maxPacketSize: 0,
charsetNumber: 33,
clientFlags: 193487
}
最后附上mysql的README:https://github.com/mysqljs/mysql