mybatis中#{}和${}的区别及order by的sql注入问题
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的sql注入问题的更多相关文章
- 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 中#{}与${}的区别 (面试题)
MyBatis/Ibatis中#和$的区别 1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号. 如:order by #user_id#,如果传入的值是111,那么解析成sql时的 ...
- [入坑系列] Mybatis 中$与#的区别
1.理解 1 #是将传入的值当做字符串的形式,eg:select id,name,age from student where id =#{id},当前端把id值1,传入到后台的时候,就相当于 sel ...
- MyBatis中#{}和${}的区别详解
首先看一下下面两个sql语句的区别: <select id="selectByNameAndPassword" parameterType="java.util.M ...
- mybatis中#{}和${}的区别
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111&qu ...
- spring中@param和mybatis中@param使用区别
spring中@param /** * 查询指定用户和企业关联有没有配置角色 * @param businessId memberId * @return */ int selectRoleCount ...
- mybatis中 #跟$的区别
#相当于对数据 加上 双引号,$相当于直接显示数据 1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是111,那么解析成sq ...
随机推荐
- 043、Java中逻辑运算之实现位与操作
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- 7.8 Varnish 其他命令
- 不可不知的spark shuffle
shuffle概览 一个spark的RDD有一组固定的分区组成,每个分区有一系列的记录组成.对于由窄依赖变换(例如map和filter)返回的RDD,会延续父RDD的分区信息,以pipeline的形式 ...
- ELK之 elasticsearch ES集群 head安装
最近项目用到 jenkins ELK 也在一次重新学习了一次 jenkins 不用说了 玩得就是 插件 + base---shell , ELK 这几年最流得log收集平台,当然不止 ...
- VLC搭建RTSP服务器的过程
第一步,打开VLC 第二步:在媒体下拉菜单下!有一个子菜单“串流”如图所示: 点击“串流”子菜单 弹出一个窗口!如下图所示. 添加一个你要串流的本地文件,我刚才传给你的那个长一点的文件. 第三步,会出 ...
- nginx proxy_pass解释
在当前大部分对外提供的web服务会使用nginx做负载均衡,日常相关的proxy_pass设置有: 以http://192.168.1.101/proxy/test.html进行访问为例子 第一种: ...
- jQuery原理系列-css选择器实现
jQuery最强大的功能在于它可以通过css选择器查找元素,它的源码中有一半是sizzle css选择器引擎的代码,在html5规范出来之后,增加了document.querySelector和doc ...
- python进阶—OpenCV之常用图像操作函数说明(转)
文章目录cv2.thresholdcv2.bitwise_andcv2.bitwise_orcv2.bitwise_notcv2.inRangecv2.resizecv2.adaptiveThresh ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 数据抽象
数据抽象是指,只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要的信息而不呈现细节. 数据抽象是一种依赖于接口和实现分离的编程(设计)技术. 它们向外界提供了大量用于操作对象数据的公共方法,也 ...
- input防抖动
input及时搜索,输入一个字符就去处理请求数据.但是还没有输入完就开始频繁请求,进行处理 <body> <input id="put"/> </bo ...