由 Mybatis 源码畅谈软件设计(四):动态 SQL 执行流程

由 Mybatis 源码畅谈软件设计(四):动态 SQL 执行流程

💡 原文中文,约7900字,阅读约需19分钟。
📝

内容提要

本文探讨了动态 SQL 的执行流程,强调动态 SQL 与静态 SQL 的区别。动态 SQL 通过 SqlNode 实现,遵循单一职责原则,并使用装饰器模式。动态 SQL 的上下文信息由 DynamicContext 创建,处理动态标签并拼接 SQL。#{} 占位符通过 JDBC 的 PreparedStatement 绑定参数,避免 SQL 注入风险,而 $ 占位符则直接拼接,存在注入风险。

🎯

关键要点

  • 动态 SQL 的执行流程与静态 SQL 有明显区别,主要通过 SqlNode 实现。

  • 动态 SQL 遵循单一职责原则,并使用装饰器模式来增强代码可读性。

  • 动态 SQL 的上下文信息由 DynamicContext 创建,处理动态标签并拼接 SQL。

  • 使用 #{} 占位符时,JDBC 的 PreparedStatement 会绑定参数,避免 SQL 注入风险。

  • 使用 $ 占位符时,SQL 直接拼接,存在 SQL 注入风险。

  • 动态标签的处理逻辑使用了装饰器模式和静态代理模式,增强了 SQL 处理的灵活性。

  • IfSqlNode 通过 OGNL 表达式判断条件,决定是否拼接 SQL 片段。

  • 动态 SQL 的最终处理结果可能包含 ? 占位符,后续逻辑与静态 SQL 执行流程相同。

🔎

延伸解读

动态 SQL 与静态 SQL 的关键区别

动态 SQL 和静态 SQL 的执行流程存在显著差异。动态 SQL 通过 SqlNode 实现,能够根据上下文动态生成 SQL 语句,而静态 SQL 则是预定义的固定语句。这种灵活性使得动态 SQL 更适合处理复杂查询,但也增加了实现的复杂度。

SQL 注入风险的防范

在使用动态 SQL 时,#{} 占位符通过 JDBC 的 PreparedStatement 绑定参数,有效避免了 SQL 注入风险。而 $ 占位符则直接拼接 SQL,存在注入风险。开发者在使用动态 SQL 时需特别注意占位符的选择,以确保安全性。

设计模式的应用

动态 SQL 的实现中运用了单一职责原则和装饰器模式,这不仅增强了代码的可读性,也使得 SQL 处理逻辑更加清晰。理解这些设计模式的应用,有助于开发者在其他项目中提升代码质量和维护性。

延伸问答

动态 SQL 和静态 SQL 有什么区别?

动态 SQL 通过 SqlNode 实现,能够根据上下文信息拼接 SQL,而静态 SQL 则是固定的 SQL 语句。

如何避免 SQL 注入风险?

使用 #{} 占位符时,JDBC 的 PreparedStatement 会绑定参数,从而避免 SQL 注入风险。

动态 SQL 的上下文信息是如何创建的?

动态 SQL 的上下文信息由 DynamicContext 创建,用于处理动态标签并拼接 SQL。

动态标签的处理逻辑是怎样的?

动态标签的处理逻辑使用了装饰器模式和静态代理模式,以增强 SQL 处理的灵活性。

IfSqlNode 是如何工作的?

IfSqlNode 通过 OGNL 表达式判断条件,如果条件为真,则将对应的 SQL 片段拼接到 SQL 中。

使用 $ 占位符会有什么风险?

使用 $ 占位符时,SQL 直接拼接,存在 SQL 注入风险,因为它不会进行参数绑定。

🏷️

标签

➡️

继续阅读