• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

MyBatis中使用$和#所遇到的问题及解决办法

java 搞代码 4年前 (2022-01-05) 38次浏览 已收录 0个评论

这篇文章主要介绍了MyBatis中使用$和#所遇到的问题及解决办法的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下

在上篇文章给大家介绍了Mybatis中#{}和${}传参的区别及#和$的区别小结,如果大家有需要可以参考下。

$和#简单说明:

#相当于对数据 加上 双引号,$相当于直接显示数据。

一、总结

  mybatis中使用sqlMap进行sql查询时,经常需要动态传递参数。动态SQL是mybatis的强大特性之一,也是它优于其他ORM框架的一个重要原因。mybatis在对sql语句进行预编译之前,会对sql进行动态解析,解析为一个BoundSql对象,也是在此处对动态SQL进行处理的。在动态 SQL 解析阶段,#{ }和${ }会有不同的表现,#{ }解析为一个JDBC预编译语句(prepared statement)的参数标记符。

  一个 #{ } 被解析为一个参数占位符 ? 。${ } 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换。

二、Bug描述

前端传入参数:

skip:0
take:10
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())) return null; 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) return null; StringBuffer buf = new StringBuffer(); for (int i = 0; i <queryStrs.length; i++) { if (i != 0) buf.append(","); buf.append("'").append(queryStrs[i]).append("'"); } return buf.toString(); } }

Mapper层处理:

 //错误的处理  AND a.rule_name IN (#{ruleName})  //正确的处理  AND a.rule_name IN (${ruleName}) 

日志描述:

 [DEBUG] [2016-08-02 17:42:42.226] [qtp1457334982-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] [2016-08-02 17:42:42.226] [qtp1457334982-157] java.sql.PreparedStatement - ==> Parameters: 'A','B'(String), 0(Integer), 10(Integer)

结果分析:mapper层对sql有预编译处理,对于#有占位符?,但是对于$会直接替换。

PS:MyBatis排序时使用order by 动态参数时需要注意,用$而不是#

字符串替换

 默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语来源gaodaima#com搞(代@码网句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:

代码如下:
 ORDER BY ${columnName}

 这里MyBatis不会修改或转义字符串。

重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。

以上就是MyBatis中使用$和#所遇到的问题及解决办法的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:MyBatis中使用$和#所遇到的问题及解决办法

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址