mybatis中#{}与${}区别

mybatis 中使用 sqlMap 进行 sql 查询时,经常需要动态传递参数,例如sql 如下:

mybatis中#{}与${}区别

select * from student where uid=#{uid} AND student_name='${studentName}'

在动态 SQL 解析阶段, #{ } 和 ${ } 会有不同的表现:

#{ } 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符占位符 ?。

上面的例子就被解析为

...... uid=?

${ } 仅仅为一个纯碎的 string 替换,在mybatis的动态 SQL 解析阶段将会进行变量替换。比如:传入的studentName参数是“张三”

...... student_name='张三'

最后解析完成的完整语句就是

select * from student where uid= ? AND student_name='张三'

然后把解析好的语句在通过JDBC执行。

所以因为在${ } 在预编译之前已经被变量替换了,这会存在 sql 注入问题。比如:传入的studentName参数是“1' OR '1'='1”

在mybatis中解析完成后变成了

select * from student where uid= ? AND student_name='1' OR '1'='1'

这样就查询出所有的数据了。

源码查看:

在执行mybtis的查询是,会执行到PreparedStatementHandler#query,查看生成的PreparedStatement

如果传入参数传入的studentName参数是“1' OR '1'='1”

所以就出现注入的情况了。

如果我们把${studentName}换成#{studentName},在传入“1' OR '1'='1”呢

在mybatis解析出的结果

在数据库的执行日志中查询执行的sql语句

发现我们传入的“'”被转义了,

所以通过预编译,用占位符的方式传值可以把一些特殊的字符进行转义,这样可以防止一些sql注入。

其原因就是:采用了JDBC的PreparedStatement,就会将sql语句:“select * from student where uid= ? AND student_name= ?” 预先编译好,也就是SQL引擎会预先进行语法分析,产生语法树,生成执行计划,也就是说,后面你输入的参数,无论你输入的是什么,都不会影响该SQL语句的语法结构了,因为语法分析已经完成了,而语法分析主要是分析sql命令,比如select,from,where,and,or,order by等等。所以即使你后面输入了这些sql命令,也不会被当成sql命令来执行了,因为这些SQL命令的执行,必须先得通过语法分析,生成执行计划,既然语法分析已经完成,已经预编译过了,那么后面输入的参数,是绝对不可能作为SQL命令来执行的,只会被当做字符串字面值参数。所以的sql语句预编译可以防御SQL注入。而且在多次执行同一个SQL时,能够提高效率。原因是SQL已编译好,再次执行时无需再编译。

默认使用PreparedStatement是不能执行预编译的,这需要在url中给出useServerPrepStmts=true参数(MySQL Server 4.1之前的版本是不支持预编译的,而Connector/J在5.0.5以后的版本,默认是没有开启预编译功能的)。

例如:jdbc:mysql://localhost:3306/test?useServerPrepStmts=true

这样才能保证mysql驱动会先把SQL语句发送给服务器进行预编译,然后在执行executeQuery()时只是把参数发送给服务器。

版权声明

1 本文地址:https://www.sunlonger.com/jijin/1230234.html 转载请注明出处。
2 本站内容除隼龙儿财经签约编辑原创以外,部分来源网络由互联网用户自发投稿及AIGC生成仅供学习参考。
3 文章观点仅代表原作者本人不代表本站立场,并不完全代表本站赞同其观点和对其真实性负责。
4 文章版权归原作者所有,部分转载文章仅为传播更多信息服务用户,如信息标记有误请联系管理员。
5 本站禁止以任何方式发布转载违法违规相关信息,如发现本站有涉嫌侵权/违规及任何不妥内容,请第一时间联系我们申诉反馈,经核实立即修正或删除。


本站仅提供信息存储空间服务,部分内容不拥有所有权,不承担相关法律责任。
上一篇 2024年06月17日
下一篇 2024年06月17日

相关推荐

  • 以下是几种构建指数基金组合的常用方法: 一、核心

    以下是几种构建指数基金组合的常用方法:一、核心 - 卫星策略1.核心资产配置●选择宽基指数基金作为核心资产,如沪深300指数基金。沪深300涵盖了沪深两市规模大、流动性好的300只股票,能代表A股市场的整体表现。这部分资产通常占组合的较大比例,比如60% - 70%。其作用是获取

    2024-10-28 22:02:12
    0 0
  • A500投资锦囊,来了

    风险提示:基金有风险,投资须谨慎。本观点仅代表当时观点,今后可能发生改变,仅供参考,不构成投资建议或保证,亦不作为任何法律文件。基金过往业绩并不预示其未来表现,基金管理人管理的其他基金的业绩并不构成基金业绩表现的保证。我国基金运作时间较短,不能反映股市发展

    2024-10-28 22:02:07
    0 0
  • 李稻葵谈理财:假如有10万元,会先买1万元保险,再买8万元基金

    近日,清化大学中国经济思想与实践研究院院长李稻葵做客央视财经频道《对话》栏目,对当前宏观经济运行情况发表最新见解。现场,李稻葵被问假如有10万元,该如何分配。李稻葵表示:“首先有个小前提,就是这10万元钱我5年之内不需要急用。首先,我想至少拿出1万元钱买保险,我

    2024-10-28 22:01:57
    0 0
  • 指数基金的三种配置方法

    1976年6月,先锋领航发行了旗下第一款指数基金产品,甚至其名称都叫做First Index Investment Trust(现已改名为Vanguard 500 Index Fund ETF——标普500ETF先锋领航)。这只产品的“第一”,不仅预示着先锋领航指数基金业务的开端,同时也标志着全球指数基金产品0的突破。投

    2024-10-28 21:23:17
    0 0
  • 基金投资:稳健获利的策略选择

    在当今的金融市场中,基金投资已成为众多投资者的热门选择。然而,如何进行有效的基金投资却是一门需要深入研究的学问。基金投资的风险、流动性和收益性一直是投资者关注的焦点。过高的风险可能导致本金的大幅损失,而缺乏流动性则可能在急需资金时陷入困境,当然,追求高收益

    2024-10-28 21:23:13
    0 0
  • 权益理财三季度跑输主流指数和权益型基金,施罗德交银理财欲推新品布局红利策略丨机警理财日报

    南财理财通课题组 黄桂煊榜单排名来自理财通AI全自动化实时排名,如您对数据有疑问,请在文末联系助理进一步核实。权益类理财三季度涨8.98%,跑输主流指数和权益型基金2024年三季度,A股出现V型反转,上证指数在第二季度末跌破3000点之后持续下行,9月20日最低至2700点,9月底

    2024-10-28 21:23:09
    0 0

发表回复

8206

评论列表(0条)

    暂无评论