从源码角度理解Mybatis的$和#的作用

理解 MyBatis 中 $# 的作用需要从其源码实现角度来解释。在 MyBatis 中,$ 符号和 # 符号的主要作用是在动态 SQL 中替代参数,并生成最终的 SQL 语句。下面是对它们的源码解析:

  1. $ 符号的作用:

    当 MyBatis 解析 SQL 语句时,会将 $ 符号作为字符串替换处理。具体来说,MyBatis 会在 SQL 语句中找到 $ 符号所对应的变量,并将其替换为变量的实际值,然后将最终的 SQL 语句发送到数据库执行。

    这种处理方式在源码中的体现主要是在 org.apache.ibatis.scripting.xmltags.TextSqlNode 类的 apply() 方法中,该方法会对 SQL 语句中的 ${} 占位符进行处理,并将其替换为实际的参数值。

    $ 符号的作用可以总结为直接替换参数值到 SQL 语句中,但是由于是字符串替换的方式,因此容易受到 SQL 注入攻击的影响。

  2. # 符号的作用:

    $ 符号不同,# 符号在 MyBatis 中主要用于参数占位,以防止 SQL 注入攻击。在解析 SQL 语句时,MyBatis 会将 # 符号作为参数占位符处理,并将参数值以预编译的方式传递给 JDBC 执行器。

    在源码中,# 符号的处理体现在 org.apache.ibatis.scripting.xmltags.TextSqlNode 类的 apply() 方法中,该方法会将 # 符号替换为 JDBC 预编译的占位符 ?,并将参数值传递给 JDBC 执行器。

    通过预编译的方式,# 符号能够防止 SQL 注入攻击,因为参数值不会直接拼接到 SQL 语句中,而是以参数占位符的形式传递给数据库。

总的来说,从源码角度理解 MyBatis 中 $# 的作用,可以看到它们在解析 SQL 语句时的不同处理方式。$ 符号直接替换参数值到 SQL 语句中,而 # 符号通过预编译的方式传递参数值,以防止 SQL 注入攻击。因此,在编写动态 SQL 语句时,推荐使用 # 符号来传递参数,以提高应用程序的安全性。

为什么默认使用的语句是PrepareStatementHandler:

在 MyBatis 中,默认使用 PrepareStatementHandler 的主要原因是其提供了预编译 SQL 的能力,这有助于提高 SQL 执行的性能和安全性。下面是几个原因:

  1. 性能优化: PrepareStatementHandler 可以对 SQL 语句进行预编译,生成一个 SQL 执行计划,并将参数值以参数占位符的形式传递给数据库。这样可以减少 SQL 语句的解析时间,并提高 SQL 执行的效率,特别是对于频繁执行的 SQL 查询而言,性能提升会更加显著。

  2. 安全性: 使用 PrepareStatementHandler 可以有效防止 SQL 注入攻击,因为参数值是以预编译的方式传递给数据库,而不是直接拼接到 SQL 语句中。这样可以保证参数值不会被误解释为 SQL 语句的一部分,从而避免了恶意用户利用参数值执行恶意 SQL 语句的风险。

  3. 数据库兼容性: PrepareStatementHandler 在各种数据库中都有良好的兼容性,因为大多数数据库都支持 SQL 的预编译执行方式。这样,MyBatis 可以在不同的数据库中保持一致的 SQL 执行方式,而无需针对不同的数据库做特殊处理。

  4. 可维护性: PrepareStatementHandler 提供了较高的代码可维护性,因为它可以将 SQL 语句与参数值分离开来,使得 SQL 语句的编写更加清晰简洁。此外,由于 SQL 语句是预编译的,因此可以方便地进行重用和调整,减少了代码的重复编写。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值