广州大麦电商忽悠是骗人的吗

声明:这是转载的。
mybatis中的#和$的区别
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by &111&, 如果传入的值是id,则解析成的sql为order by &id&.
2. $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id, &如果传入的值是id,则解析成的sql为order by id.
3. #方式能够很大程度防止sql注入。
4.$方式无法防止Sql注入。
5.$方式一般用于传入数据库对象,例如传入表名.
6.一般能用#的就别用$.
防止Sql注入
注意:SQL语句不要写成select * from t_stu where s_name like '%$name$%',这样极易受到注入攻击。
”${xxx}”这样格式的参数会直接参与sql编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式。
在编写mybatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止sql注入攻击。
&sql id=&condition_where&&
&isNotEmpty property=&companyName& prepend=& and &&
t1.company_name like #companyName#
&/isNotEmpty&
java代码和你原来的差不多,其实也没什么不好,你要觉得麻烦 把判断null和'%'封装到一个方法里就可以了&
if (!StringUtil.panyName)) {
table.setCompanyName(&%& + panyName + &%&);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:169853次
积分:2337
积分:2337
排名:第12744名
原创:30篇
转载:167篇
评论:39条
(5)(9)(5)(4)(2)(2)(2)(2)(4)(4)(1)(5)(2)(6)(6)(2)(4)(2)(1)(2)(2)(4)(1)(1)(2)(1)(1)(1)(3)(2)(4)(3)(6)(1)(9)(9)(3)(4)(6)(6)(12)(1)(2)(5)(2)(2)(1)(3)(10)(1)(1)(2)(2)(5)(4)(1)(2)(3)(1)2016年1月 Java大版内专家分月排行榜第一2015年12月 Java大版内专家分月排行榜第一2015年9月 Java大版内专家分月排行榜第一2015年8月 Java大版内专家分月排行榜第一
2016年3月 Java大版内专家分月排行榜第二2016年2月 Java大版内专家分月排行榜第二2015年11月 Java大版内专家分月排行榜第二2015年10月 Java大版内专家分月排行榜第二
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。MyBatis中使用$和#所遇到的问题及解决办法
作者:RunforLove
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了MyBatis中使用$和#所遇到的问题及解决办法的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
在上篇文章给大家介绍了,如果大家有需要可以参考下。
$和#简单说明:
#相当于对数据 加上 双引号,$相当于直接显示数据。
  mybatis中使用sqlMap进行sql查询时,经常需要动态传递参数。动态SQL是mybatis的强大特性之一,也是它优于其他ORM框架的一个重要原因。mybatis在对sql语句进行预编译之前,会对sql进行动态解析,解析为一个BoundSql对象,也是在此处对动态SQL进行处理的。在动态 SQL 解析阶段,#{ }和${ }会有不同的表现,#{ }解析为一个JDBC预编译语句(prepared statement)的参数标记符。
  一个 #{ } 被解析为一个参数占位符 ? 。${ } 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换。
二、Bug描述
前端传入参数:
ruleName:A,B,C
业务层处理:
package SQL;
* 将前端多选参数转义为SQL语句内容
public class SQLUtil {
private final static String REPLACECHAR_COMMA = ",";
private final static String REPLACECHAR_SEMICOLON = ";";
public static void main(String[] args) {
String s1 = "A,B,C";
String s2 = "A B C";
System.out.println("逗号分隔:" + formatInStr(s1));
System.out.println("空格分隔:" + formatInStr(s2));
private static String formatInStr(String queryStr) {
return queryInStr(sliptQueryStr(queryStr));
private static String[] sliptQueryStr(String queryStr) {
if (null == queryStr || "".equals(queryStr.trim()))
queryStr = queryStr.replaceAll(SQLUtil.REPLACECHAR_COMMA, " ").replaceAll(REPLACECHAR_SEMICOLON, " ");
return queryStr.split("\\s+");
private static String queryInStr(String[] queryStrs) {
if (null == queryStrs || 0 == queryStrs.length)
StringBuffer buf = new StringBuffer();
for (int i = 0; i & queryStrs. i++) {
if (i != 0) buf.append(",");
buf.append("'").append(queryStrs[i]).append("'");
return buf.toString();
Mapper层处理:
//错误的处理
&if test="ruleName != null and ruleName != ''"&
AND a.rule_name IN (#{ruleName})
//正确的处理
&if test="ruleName != null and ruleName != ''"&
AND a.rule_name IN (${ruleName})
日志描述:
[DEBUG] [ 17:42:42.226] [qtp-157] java.sql.Connection - ==& Preparing: SELECT a.id, a.is_valid, a.rule_lable, a.rule_name, a.type, b.sp_id, b.sp_name,       a.rule_content, c.user_name, a.gmt_modified, a.ordering FROM idc_logistics_assign_rules a LEFT JOIN app_user c on c.work_no=a.modifier and c.is_deleted='n',       idc_sp_info b WHERE a.is_deleted = 'n' AND b.is_deleted = 'n' AND a.sp_id = b.sp_id AND a.rule_name IN (?) ORDER BY ordering asc limit ?, ?
[DEBUG] [ 17:42:42.226] [qtp-157] java.sql.PreparedStatement - ==& Parameters: 'A','B'(String), 0(Integer), 10(Integer)
结果分析:mapper层对sql有预编译处理,对于#有占位符?,但是对于$会直接替换。
PS:MyBatis排序时使用order by 动态参数时需要注意,用$而不是#
字符串替换
&默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
&ORDER BY ${columnName}
&这里MyBatis不会修改或转义字符串。
重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具sql注入大家都不陌生,是一种常见的攻击方式,攻击者在界面的表单信息或url上输入一些奇怪的sql片段,例如&or &1&=&1&&这样的语句,有可能入侵参数校验不足的应用程序。所以在我们的应用中需要做一些工作,来防备这样的攻击方式。在一些安全性很高的应用中,比如银行软件,经常使用将sql语句全部替换为存储过程这样的方式,来防止sql注入,这当然是一种很安全的方式,但我们平时开发中,可能不需要这种死板的方式。
mybatis框架作为一款半自动化的持久层框架,其sql语句都要我们自己来手动编写,这个时候当然需要防止sql注入。其实Mybatis的sql是一个具有&输入+输出&功能,类似于函数的结构,如下:
&select id=&getBlogById& resultType=&Blog& parameterType=&int&&
select id,title,author,content from blog where id=#{id}
这里,parameterType标示了输入的参数类型,resultType标示了输出的参数类型。回应上文,如果我们想防止sql注入,理所当然地要在输入参数上下功夫。上面代码中高亮部分即输入参数在sql中拼接的部分,传入参数后,打印出执行的sql语句,会看到sql是这样的:
select&id,title,author,content&from&blog where id = ?
不管输入什么参数,打印出的sql都是这样的。这是因为mybatis启用了预编译功能,在sql执行前,会先将上面的sql发送给数据库进行编译,执行时,直接使用编译好的sql,替换占位符&?&就可以了。因为sql注入只能对编译过程起作用,所以这样的方式就很好地避免了sql注入的问题。
mybatis是如何做到sql预编译的呢?其实在框架底层,是jdbc中的PreparedStatement类在起作用,PreparedStatement是我们很熟悉的Statement的子类,它的对象包含了编译好的sql语句。这种&准备好&的方式不仅能提高安全性,而且在多次执行一个sql时,能够提高效率,原因是sql已编译好,再次执行时无需再编译。
话说回来,是否我们使用mybatis就一定可以防止sql注入呢?当然不是,请看下面的代码:&
&select id=&orderBlog& resultType=&Blog& parameterType=&map&&
select id,title,author,content from blog order by ${orderParam}
仔细观察,内联参数的格式由&#{xxx}&变为了${xxx}。如果我们给参数&orderParam&赋值为&id&,将sql打印出来,是这样的:
select id,title,author,content from&blog order by id
显然,这样是无法阻止sql注入的。在mybatis中,&${xxx}&这样格式的参数会直接参与sql编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用&${xxx}&这样的参数格式,所以,这样的参数需要我们在代码中手工进行处理来防止注入。
结论:在编写mybatis的映射语句时,尽量采用&#{xxx}&这样的格式。若不得不使用&${xxx}&这样的参数,要手工地做好过滤工作,来防止sql注入攻击。
阅读(...) 评论()}

我要回帖

更多关于 广州大麦电商忽悠 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信