mybatis的#{}和${}的区别以及order by注入问题
前言略,直奔主题..
#{}相当于jdbc中的preparedstatement
${}是输出变量的值
你可能说不明所以,不要紧我们看2段代码:
String sql = "select * from admin_domain_location order by ?";
PreparedStatement st = con.prepareStatement(sql);
st.setString(1, "domain_id");
System.out.println(st.toString());
ResultSet rs = st.executeQuery();
while(rs.next()){
System.out.println(rs.getString("domain_id"));
}
输出结果:
com.mysql.jdbc.PreparedStatement@1fa1ba1: select * from admin_domain_location order by 'domain_id'
3
4
5
2
6
这是个jdbc的preparedstatement例子,不要吐槽我这么写是否合法,这里只是为了说明问题.
以上例子有得出以下信息:
1)order by后面如果采用预编译的形式动态输入参数,那么实际插入的参数是一个字符串,例子中是:order by 'domain_id'
2)输出结果并没有排序,从sql语句中的形式我们也可以推测出此sql语句根本也不合法(正常应该是 order by domain_id)
修改以上代码如下:
String input = "domain_id";
String sql = "select * from admin_domain_location order by "+input;
PreparedStatement st = con.prepareStatement(sql);
System.out.println(st.toString());
ResultSet rs = st.executeQuery();
while(rs.next()){
System.out.println(rs.getString("domain_id"));
}
输出结果:
com.mysql.jdbc.PreparedStatement@1fa1ba1: select * from admin_domain_location order by domain_id
2
3
4
5
6
此次我们直接把一个变量的值拼接sql语句,从结果可以看出来:
1)sql语句拼接正常
2)查询结果排序正常
你可能要问这和#{}与${}有什么关系..
上面已经说过#{}相当于jdbc的preparedstatement,所以以上的第一个例子就相当于#{},那么第二个例子就自然而然指的是${}的情况.
你可能说思维还是有些凌乱,不要紧我们来看第三个例子:
String sql = "select * from admin_domain_location where domain_id=?";
PreparedStatement st = con.prepareStatement(sql);
st.setString(1, "2");
System.out.println(st.toString());
ResultSet rs = st.executeQuery();
while(rs.next()){
System.out.println(rs.getString("domain_id"));
}
=======================================
String input = "2";
String sql = "select * from admin_domain_location where domain_id='"+input+"'";
PreparedStatement st = con.prepareStatement(sql);
System.out.println(st.toString());
ResultSet rs = st.executeQuery();
while(rs.next()){
System.out.println(rs.getString("domain_id"));
} 输出结果都为:
com.mysql.jdbc.PreparedStatement@12bf560: select * from admin_domain_location where domain_id='2'
2
这第三个例子说的是#{}和${}通用的问题,也就是说在此种情况下#{}和${}是通用的,只不过需要些小的转换.如例子中需要手动
拼接单引号 ' ' 到变量值的前后,确保sql语句正常.
简单说#{}是经过预编译的,是安全的,而${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在sql注入.
这里先说一下只能${}的情况,从我们前面的例子中也能看出,order by是肯定只能用${}了,用#{}会多个' '导致sql语句失效.此外还有一个like 语句后也需要用${},简单想一下
就能明白.由于${}仅仅是简单的取值,所以以前sql注入的方法适用此处,如果我们order by语句后用了${},那么不做任何处理的时候是存在sql注入危险的.你说怎么防止,那我只
能悲惨的告诉你,你得手动处理过滤一下输入的内容,如判断一下输入的参数的长度是否正常(注入语句一般很长),更精确的过滤则可以查询一下输入的参数是否在预期的参数集合中..
mybatis的#{}和${}的区别以及order by注入问题的更多相关文章
- mybatis中#{}和${}的区别及order by的sql注入问题
mybatis的#{}和${}的区别以及order by注入问题 原文 http://www.cnblogs.com/chyu/p/4389701.html 前言略,直奔主题.. #{}相当于j ...
- MyBatis中#{ }和${ }的区别,数据库优化遵循层次和查询方法
MyBatis中#{ }和${ }的区别详解 1.#将传入的数据当成一个字符串,会对自动传入的数据加一个 双引号. 例如order by #id#,如果传入的值是111,那么解析成sql时变为orde ...
- mybatis中的#{}和${}区别
mybatis中的#{}和${}区别 2017年05月19日 13:59:24 阅读数:16165 1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #use ...
- Mybatis笔记八:MyBatis中#{}和${}的区别
先给大家介绍下MyBatis中#{}和${}的区别,具体介绍如下: 1. $将传入的数据直接显示生成在sql中 2. #方式能够很大程度防止sql注入. 3.$方式无法防止Sql注入. 4.$方式一般 ...
- Mybatis与Ibatis的区别
Mybatis与Ibatis的区别: 1.Mybatis实现了接口绑定,使用更加方便 在ibatis2.x中我们需要在DAO的实现类中指定具体对应哪个xml映射文件, 而Mybatis实现了DAO接口 ...
- mybatis与hibernate的区别持久层对比【面试题】
Mybatis技术特点: 好处: 通过直接编写SQL语句,可以直接对SQL进行性能的优化: 学习门槛低,学习成本低.只要有SQL基础,就可以学习mybatis,而且很容易上手: 由于直接编写SQL语句 ...
- JavaWeb_(Mybatis框架)JDBC操作数据库和Mybatis框架操作数据库区别_一
系列博文: JavaWeb_(Mybatis框架)JDBC操作数据库和Mybatis框架操作数据库区别_一 传送门 JavaWeb_(Mybatis框架)使用Mybatis对表进行增.删.改.查操作_ ...
- 【ORM】Mybatis与JPA的区别
Mybatis与JPA的区别: 1.ORM映射不同: Mybatis是半自动的ORM框架,提供数据库与结果集的映射: JPA(Hibernate)是全自动的ORM框架,提供对象与数据库的映射: 2.可 ...
- order by 注入姿势
order by 注入原理 其实orde by 注入也是sql注入的一种,原理都一样就是mysql语法的区别,order by是用来排序的语法. sql-lab讲解 判断方法 1.通过做运算来判断如: ...
随机推荐
- [爬虫学习笔记]用于提取网页中所有链接的 Extractor 模块
Extractor的工作是从下载的网页中将它包含的所有URL提取出来.这是个细致的工作,你需要考虑到所有可能的url的样式,比如网页中常常会包含相对路径的url,提取的时候需要将它转换 ...
- 泛函编程(19)-泛函库设计-Parallelism In Action
上节我们讨论了并行运算组件库的基础设计,实现了并行运算最基本的功能:创建新的线程并提交一个任务异步执行.并行运算类型的基本表达形式如下: import java.util.concurrent._ o ...
- Struts2执行过程解析
说到Struts2执行过程就少不了一张图: 1 客户端初始化一个指向Servlet容器的请求: 2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextClea ...
- Follow me to learn what is repository pattern
Introduction Creating a generic repository pattern in an mvc application with entity framework is th ...
- spring编程式刷新/重新加载applicationcontext/dispatchservlet(正确版)
有些时候,尤其是在开发应用框架的时候,由于某些原因无法或者很难重启tomcat或者reload应用,但是配置又需要动态生效,这个时候通常希望通过reload spring applicationcon ...
- Android:TextView 自动滚动(跑马灯) (转)
Android:TextView 自动滚动(跑马灯) TextView实现文字滚动需要以下几个要点: 1.文字长度长于可显示范围:android:singleLine="true ...
- [ASP.NET MVC] 使用Bootstrap套件
[ASP.NET MVC] 使用Bootstrap套件 前言 在开发Web项目的时候,除了一些天赋异禀的开发人员之外,大多数的开发人员应该都跟我一样,对于如何建构出「美观」的用户接口而感到困扰.这时除 ...
- lambda 个人学习理解
lambda是简化代码量的写用更简单的方法来写匿名方法 lambda左边是参数,右边是代码块(方法执行语句). 整体运算结果是根据左边参数,执行右边语句,返回右边执行的结果: 匿名方法是简化方法 1. ...
- IP 协议首部格式与其配套使用的四个协议(ARP,RARP,ICMP,IGMP)
目录 IP协议首部格式地址解析协议 ARP逆向地址解析协议 RARP网际控制报文协议 ICMP网际组管理协议IGMP IP 数据报首部 IP数据报首部格式: 最高位在左边,记为0 bit:最低位在右边 ...
- 谷歌的网页排序算法(PageRank Algorithm)
本文将介绍谷歌的网页排序算法(PageRank Algorithm),以及它如何从250亿份网页中捞到与你的搜索条件匹配的结果.它的匹配效果如此之好,以至于“谷歌”(google)今天已经成为一个被广 ...