简单学习一下 MyBatis 动态SQL使用及原理( 二 )


八、动态SQL解析原理MyBatis的动态SQL是通过OGNL表达式来实现的 。OGNL(Object-Graph Navigation Language)是一种基于Java对象图遍历的表达式语言,它可以方便地访问Java对象的属性和方法 。
在MyBatis中,通过OGNL表达式可以动态地计算条件是否成立,从而确定是否将SQL片段添加到最终的SQL语句中 。OGNL表达式通常嵌入在MyBatis中的动态SQL标签中,例如if、choose、when、otherwise等 。
MyBatis使用了两个重要的类来实现OGNL表达式的解析和计算:OgnlExpressionEvaluator和OgnlCache 。OgnlExpressionEvaluator类负责将MyBatis传入的参数对象转换为OGNL表达式需要的上下文对象,然后将OGNL表达式计算结果返回;OgnlCache类负责缓存已经解析好的OGNL表达式,避免重复解析和计算 。
具体的解析过程如下:

  1. 根据MyBatis的配置将MApper.xml文件中的SQL语句解析为一个MappedStatement对象,并将其中的OGNL表达式解析成一个一个可执行的SQL片段 。
  2. 对于每一个OGNL表达式,MyBatis使用${}来表示一个简单的OGNL表达式,使用#{}来表示一个OGNL表达式中包含复杂逻辑的情况 。在解析过程中,MyBatis会将OGNL表达式中的参数进行解析和预处理,然后使用OgnlCache类将其缓存起来 。
  3. 当Mapper接口方法被调用时,MyBatis会将方法中传入的参数对象转换为一个BoundSql对象,并将该BoundSql对象与MappedStatement对象一起传递给OgnlExpressionEvaluator类 。
  4. OgnlExpressionEvaluator类中再次解析OGNL表达式,并将BoundSql对象作为上下文传入OGNL表达式中执行 。OGNL表达式执行的结果将被转化为String类型,并返回给BoundSql对象 。
  5. 最后,MyBatis将所有BoundSql对象中的SQL片段拼接成最终的SQL语句并执行 。
MyBatis的动态SQL解析原理是将OGNL表达式解析为可执行的SQL片段,然后根据条件判断是否将该SQL片段加入到最终的SQL语句中 。MyBatis使用OgnlExpressionEvaluator和OgnlCache类来实现OGNL表达式的解析和计算,从而实现动态SQL的功能 。
在 MyBatis 的源码中,动态 SQL 还涉及到以下接口和类来实现:
  1. SqlNode 接口:表示一个 SQL 节点,也就是一个 SQL 片段 。它包含一个 apply 方法,在执行 SQL 语句时会将 SQL 片段应用到相应的位置 。
  2. MixedSqlNode 类:实现了 SqlNode 接口,可以包含多个子节点 。该类的 apply 方法会依次遍历所有子节点,并将每个节点应用到 SQL 语句中 。
  3. TextSqlNode 类:表示一个纯文本节点 。该类包含一个文本字符串,可以将其直接应用到 SQL 语句中 。
  4. IfSqlNode 类:表示一个条件节点 。可以根据指定的条件判断是否需要应用该节点内部的 SQL 片段 。如果条件成立,则会将 SQL 片段应用到 SQL 语句中 。
  5. TrimSqlNode 类:表示一个修剪节点,可以根据配置对 SQL 片段进行修剪操作 。常用于处理 UPDATE 和 INSERT 语句中 SET 子句的逗号问题 。
  6. WhereSqlNode 类:表示一个 WHERE 条件节点 。可以将 WHERE 子句的参数拼接到 SQL 语句中 。

简单学习一下 MyBatis 动态SQL使用及原理

文章插图
 
以上是 MyBatis 中实现动态 SQL 的核心接口和类 。MyBatis 内部通过组合这些接口和类来构建复杂的 SQL 语句 。通过定义这些接口和类,可以让开发者更加方便地书写动态 SQL 语句,并且遵循了设计模式中的单一职责原则 。
还有一些Builder 接口及其实现类的作用都是用于构造 SQL 语句 。下面简单介绍一下一些常用的 Builder 类型:
  1. BaseBuilder 接口:所有 Builder 的基础接口,定义了一些共同的方法,例如获取 Configuration 对象、创建 ParameterMapping 对象等 。
  2. XMLMapperBuilder 类:从 XML 文件中解析出各种 SQL 节点,然后通过其他 Builder 对象将其转换成 SQL 语句 。
  3. MapperBuilderAssistant 类:辅助 XMLMapperBuilder 类创建各种类型的 SQL 节点,例如创建 <select>、<update>、<insert> 等标签节点 。
  4. SqlSourceBuilder 类:根据 XML 中的 SQL 片段创建 SqlSource 对象,SqlSource 对象中包含了解析后的 SQL 语句和参数信息 。
  5. DynamicSqlSource 类:用于处理动态 SQL,也就是包含各种条件判断和循环语句的 SQL 片段 。它是 SqlSource 接口的一种实现 。
  6. StaticSqlSource 类:用于处理静态 SQL,即不包含任何条件语句和循环语句的 SQL 片段 。它同样是 SqlSource 接口的一种实现 。


    推荐阅读