Node.js数据库操作之查询MySQL数据库(二)


Posted in Javascript onMarch 04, 2017

前言

我们在上一篇文章《Node.js数据库操作之连接MySQL数据库(一)》中已经学习了Nodejs连接MySQL数据库的几种方法,数据库连接上了之后就需要对数据库进行查询。本篇文章介绍一下查询MySQL数据库的方法。下面话不多说,来看看详细的介绍吧。

查询方式

上一篇文章中,我们用到了一种查询数据库的最基本的方法:connection.query(sqlString, callback)

第一个参数是一个SQL语句,可以是任意的数据库语句,而第二个参数是一个回调函数,查询结果通过回调参数的方式返回。

connection.query(
 'select * from book where author = "xyf" and country = "china"',
 function(err, result) {
 console.log(result);
 }
);

这是最简单的查询方式,但是存在着两个问题,一个是需要拼接字符串,比较繁琐;另一个是容易被sql注入攻击,因此我们有了第二种查询方式。

占位符注入查询

第二种查询方式是采用了占位符的形式connection.query(sqlString, values, callback) ,这样就不需要进行恶心的字符串的拼接了。

connection.query(
 'select * from book where author = ? and country = ?',
 ['xyf', 'china'], 
 function(err, result) {
 console.log(result);
 }
);

使用对象查询方式

第三种查询方式我们将查询语句和查询值组合成一个对象来进行查询。它的形式是这样的:connection.query(object, callback)

connection.query(
 {
 sql: 'select * from book where author = ? and country = ?',
 values: ['xyf', 'china'], // 作为对象的属性
 timeout: 40000,
 },
 function(err, result) {
 console.log(result);
 }
);

组合查询方式

将第二种和第三种方式可以结合起来使用,查询值作为query方法的一个参数,而不是作为对象中的一个属性。

connection.query(
 {
 sql: 'select * from book where author = ? and country = ?',
 timeout: 40000,
 // ['corner', 'us'] // 如果同时设置,那么此时不会生效
 },
 ['xyf', 'china'], // 作为query函数的一个参数
 function(err, result) {
 console.log(result);
 }
);

需要注意的是,如果我们既将查询值作为对象的属性,又将其作为query函数的参数,这个时候函数中的参数将会覆盖对象的属性,也就是说此时只有参数的值生效。

解析查询值

在进行数据库查询时,有一个重要的原则就是永远不要相信用户的输入。为什么不能相信用户的输入呢,首先让我们来了解一下SQL注入攻击。

SQL注入攻击

所谓的SQL注入攻击,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。由于笔者并不是从事数据库方面的工作,也不是数据库方面的砖家,所以只能通过一个简单的DEMO来演示一下SQL注入攻击。

假如我们拼接的SQL语句是这样的

var username = 'xyf';
var sql = 'select * from book where author = "'+username+'"';

这里我们期待用户输入的username是Jack或者LiLi之类的,但是用户说我偏不,我就输入一串恶意代码:

var username = '"1 or 1=1';
var sql = 'select * from book where author = "'+username+'"';

最后我们拼接的查询语句就变成了下面这样的:

select * from book where author = "" or 1=1

如果读者对SQL语句有一些基本了解,就会知道如果把这段查询语句放到数据库中进行查询,那么所有用户的信息都被查出来了,但是这并不是我们想要看到的结果。

避免SQL注入攻击

那么怎么才能避免SQL注入攻击呢?mysql提供了两种方法给我们,第一种方法就是每次查询时都把用户输入的数据都用escape()函数解析一下,有点类似预处理语句。

var authorname = 'user input';
connection.escape(authorname);
// 或者使用mysql.escape(authorname);
connection.query(
 'select * from book where author = "'+authorname+'"',
 function(err, result) {
 console.log(result);
 }
);

第二种方法就是在查询时通过上面说到的占位符注入查询的查询方式来进行查询。但它内部的实现也是通过上面所说的escape()方法将用户输入解析了一下。推荐使用第二种方法来得简单快捷。

多语句查询

mysql还支持多语句查询,但是由于某些安全原因(官方解释是因为如果值没有正确解析会导致SQL注入攻击)默认是被禁止的。那么让我们来打开这个“潘多拉魔盒”把。

在创建数据库连接时首先把这个功能开启。

let connection = mysql.createConnection({
 // 其他配置
 multipleStatements: true,
});

然后我们就可以使用多语句查询了。

connection.query(
 {
 sql: `select * from book where username = ?;
  select * from book where username = ?;`,
 },
 ['ace','xyf'],
 function(err, rows, fields) {
 if (err) throw err;
 console.log('The solution is: ', rows);
 }
);

查询结果

通过查询语句返回的结果以数组的形式返回,如果是单语句查询,数组就是一个纯对象数组[obj1,obj2,...],数组中的每一个对象都是数据库中每一行的数据,只是以对象的方式返回。如果没有查询到数据,那么数组的长度就为0。

但是如果是多语句(m条语句)的方式查询,虽然返回也是一个数组,但是数组中嵌套有n个数组,n的取值取决于你查询语句的条数m(即n=m)。

总结

由于官方文档比较零碎,因此整理得不是很到位,有问题的地方希望大家指正。以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
使用Jquery搭建最佳用户体验的登录页面之记住密码自动登录功能(含后台代码)
Jul 10 Javascript
热点新闻滚动特效的js代码
Aug 17 Javascript
javascript实现分栏显示小技巧附图
Oct 13 Javascript
Node.js与MySQL交互操作及其注意事项
Oct 05 Javascript
详解webpack2+node+react+babel实现热加载(hmr)
Aug 24 Javascript
简易Vue评论框架的实现(父组件的实现)
Jan 08 Javascript
使用koa2创建web项目的方法步骤
Mar 12 Javascript
详解微信小程序调用支付接口支付
Apr 28 Javascript
如何实现小程序tab栏下划线动画效果
May 18 Javascript
layui type2 通过url给iframe子页面传值的例子
Sep 06 Javascript
vue-router为激活的路由设置样式操作
Jul 18 Javascript
JavaScript通如何过RGraph实现动态仪表盘
Oct 15 Javascript
Node.js数据库操作之连接MySQL数据库(一)
Mar 04 #Javascript
jQuery实现贪吃蛇小游戏(附源码下载)
Mar 04 #Javascript
详解vue父子模版嵌套案例
Mar 04 #Javascript
vue指令以及dom操作详解
Mar 04 #Javascript
JS如何判断浏览器类型和详细区分IE各版本浏览器
Mar 04 #Javascript
详解在Vue中通过自定义指令获取dom元素
Mar 04 #Javascript
在javaScript中检测数据类型的几种方式小结
Mar 04 #Javascript
You might like
PHP中文件缓存转内存缓存的方法
2011/12/06 PHP
微信公众平台开发关注及取消关注事件的方法
2014/12/23 PHP
PHP书写格式详解(必看)
2016/05/23 PHP
Nginx下ThinkPHP5的配置方法详解
2017/08/01 PHP
PHP基于rabbitmq操作类的生产者和消费者功能示例
2018/06/16 PHP
使用jQuery实现dropdownlist的联动效果(sharepoint 2007)
2011/03/30 Javascript
javascript开发技术大全 第4章 直接量与字符集
2011/07/03 Javascript
通过遮罩层实现浮层DIV登录的js代码
2014/02/07 Javascript
jQuery表单域属性过滤器用法分析
2015/02/10 Javascript
JS选中checkbox后获取table内一行TD所有数据的方法
2015/07/01 Javascript
AngularJs Scope详解及示例代码
2016/09/01 Javascript
javascript 内置对象及常见API详细介绍
2016/11/01 Javascript
Bootstrap table表格简单操作
2017/02/07 Javascript
BootStrap select2 动态改变值的方法
2017/02/10 Javascript
JS简单添加元素新节点的方法示例
2018/02/10 Javascript
教你如何用Node实现API的转发(某音乐)
2019/09/20 Javascript
js实现鼠标切换图片(无定时器)
2021/01/27 Javascript
[03:26]回顾2015国际邀请赛中国区预选赛
2015/06/09 DOTA
python操作mysql中文显示乱码的解决方法
2014/10/11 Python
利用python3随机生成中文字符的实现方法
2017/11/24 Python
Django项目中用JS实现加载子页面并传值的方法
2018/05/28 Python
执行Django数据迁移时报 1091错误及解决方法
2019/10/14 Python
python上传时包含boundary时的解决方法
2020/04/08 Python
selenium+headless chrome爬虫的实现示例
2021/01/08 Python
西班牙第一的网上药房:PromoFarma.com
2017/04/17 全球购物
法国足球商店:Footcenter
2019/07/06 全球购物
科颜氏法国官网:Kiehl’s法国
2019/08/20 全球购物
用C或者C++语言实现SOCKET通信
2015/02/24 面试题
上班打牌检讨书
2014/02/07 职场文书
希特勒经典演讲稿
2014/05/19 职场文书
小学学校评估方案
2014/06/08 职场文书
开展批评与自我批评发言稿
2014/10/16 职场文书
2014年安全管理工作总结
2014/12/01 职场文书
爱心捐书倡议书
2015/04/27 职场文书
python基于tkinter制作下班倒计时工具
2021/04/28 Python
Python基础之教你怎么在M1系统上使用pandas
2021/05/08 Python