Mybatis的动态Sql组合模式详情

 更新时间:2022年08月18日 11:47:14   作者:周杰伦本人​​​​​​​  
这篇文章主要介绍了Mybatis的动态Sql组合模式详情,这篇文章从组合模式的角度分析了Mybatis动态sql的部分,SqlNode是组合模式的Component接口,更多相关内容需要的小伙伴可以参考一下

前言

当同一类型的很多对象组成一个树结构的时候,可以考虑使用组合模式,组合模式涉及三个类:

Component接口:定义树的各个节点的一些操作

Left类:这个是树的叶子结点,实现Component接口,对于节点的管理它不去实现,只实现业务逻辑

Composite类:这个是树的非叶子节点,实现Component接口,不但实现业务逻辑,同时会管理子节点,会有个Component接口的集合类来管理子节点

Component角色

SqlNode就是扮演组合模式中的Component角色,Sql标签会解析成SqlNode对象,

public interface SqlNode {
  boolean apply(DynamicContext context);
}

Composite角色

MixedSqlNode类扮演组合模式的Composite角色:

它也是解析<otherwise>标签的类

public class MixedSqlNode implements SqlNode {
  private final List<SqlNode> contents;

  public MixedSqlNode(List<SqlNode> contents) {
    this.contents = contents;
  }

  @Override
  public boolean apply(DynamicContext context) {
    contents.forEach(node -> node.apply(context));
    return true;
  }
}

它有个SqlNode的集合类,记录SqlNode对象,apply方法就是遍历集合,依次调用自己的apply()方法

剩余其他SqlNode的实现类就充当组合模式的Left类了:

Left类角色

TextSqlNode

TextSqlNode是包含${}的动态sql片段,它的apply()方法的实现:

  @Override
  public boolean apply(DynamicContext context) {
    GenericTokenParser parser = createParser(new BindingTokenParser(context, injectionFilter));
    context.appendSql(parser.parse(text));
    return true;
  }
  private GenericTokenParser createParser(TokenHandler handler) {
    return new GenericTokenParser("${", "}", handler);
  }

创建GenericTokenParser解析器,然后解析包含${}的sql片段,解析后保存到DynamicContext中

TrimSqlNode

TrimSqlNode是解析出的trim标签的对象,trim标签可以去除sql的and、逗号或者拼接where关键字等,

  private final SqlNode contents;
  @Override
  public boolean apply(DynamicContext context) {
    FilteredDynamicContext filteredDynamicContext = new FilteredDynamicContext(context);
    boolean result = contents.apply(filteredDynamicContext);
    filteredDynamicContext.applyAll();
    return result;
  }

先调用SqlNode 的apply方法 ,然后调用FilteredDynamicContext的applyAll()方法进行前后缀的处理,FilteredDynamicContext在DynamicContext包装了一层,利用了装饰者模式,除了DynamicContext的存储解析结果和参数功能外还能进行前后缀的处理

IfSqlNode

IfSqlNode是解析出if 标签、when标签的类,

public class IfSqlNode implements SqlNode {
  private final ExpressionEvaluator evaluator;
  private final String test;
  private final SqlNode contents;

  public IfSqlNode(SqlNode contents, String test) {
    this.test = test;
    this.contents = contents;
    this.evaluator = new ExpressionEvaluator();
  }

  @Override
  public boolean apply(DynamicContext context) {
    if (evaluator.evaluateBoolean(test, context.getBindings())) {
      contents.apply(context);
      return true;
    }
    return false;
  }
}

ExpressionEvaluator是解析工具类,test记录了if标签的test表达式,apply()方法中ExpressionEvaluator工具类解析test表达式,返回true之后调用具体SqlNode的apply()方法

StaticTextSqlNode

StaticTextSqlNode是非动态的sql片段,apply()方法直接把sql片段追加到DynamicContext的sqlBuilder属性中

public class StaticTextSqlNode implements SqlNode {
  private final String text;

  public StaticTextSqlNode(String text) {
    this.text = text;
  }

  @Override
  public boolean apply(DynamicContext context) {
    context.appendSql(text);
    return true;
  }
}

总结

这篇文章从组合模式的角度分析了Mybatis动态sql的部分,SqlNode是组合模式的Component接口,MixedSqlNode是组合模式的Composite角色,还有其他的SqlNode的实现类TextSqlNode、TrimSqlNode、IfSqlNode、StaticTextSqlNode,它们是解析不同的标签,TextSqlNode解析包含${}的动态sql片段,TrimSqlNode类解析trim标签,IfSqlNode是解析出if 标签、when标签的类,StaticTextSqlNode是非动态的sql片段

到此这篇关于Mybatis的动态Sql组合模式详情的文章就介绍到这了,更多相关Mybatis 组合模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java基础之static的用法

    Java基础之static的用法

    这篇文章主要介绍了Java基础之static的用法,文中有非常详细的代码示例,对正在学习java基础的小伙伴们有很大的帮助,需要的朋友可以参考下
    2021-05-05
  • 一步步教会你使用Java原生指令编译并运行一个程序

    一步步教会你使用Java原生指令编译并运行一个程序

    Java是一种广泛使用的编程语言,具有跨平台性和面向对象的特性,下面这篇文章主要给大家介绍了关于使用Java原生指令编译并运行一个程序的相关资料,需要的朋友可以参考下
    2024-07-07
  • mybatis基本实例详解

    mybatis基本实例详解

    这篇文章主要介绍了mybatis基本实例详解以及mybatis自由模糊查询,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-03-03
  • java计算百分比值的方法

    java计算百分比值的方法

    这篇文章主要介绍了java计算百分比值的方法,涉及java数值运算的技巧,需要的朋友可以参考下
    2015-03-03
  • Java二叉树的遍历思想及核心代码实现

    Java二叉树的遍历思想及核心代码实现

    今天小编就为大家分享一篇关于Java二叉树的遍历思想及核心代码实现,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • java实现Socket通信之单线程服务

    java实现Socket通信之单线程服务

    这篇文章主要为大家详细介绍了java实现Socket通信的单线程服务,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • IDEA配置SpringBoot热启动,以及热启动失效问题

    IDEA配置SpringBoot热启动,以及热启动失效问题

    这篇文章主要介绍了IDEA配置SpringBoot热启动,以及热启动失效问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • 关于Mybatis-plus设置字段为空的正确写法

    关于Mybatis-plus设置字段为空的正确写法

    这篇文章主要介绍了关于Mybatis-plus设置字段为空的正确写法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • 关于弗洛伊德算法求最短路径详解

    关于弗洛伊德算法求最短路径详解

    这篇文章主要介绍了关于弗洛伊德算法求最短路径详解,弗洛伊德算法VS迪杰斯特拉算法:迪杰斯特拉算法通过选定的被访问顶点,求出从出发访问顶点到其他项点的最短路径:弗洛伊德算法中每-个顶点都是出发访问点,需要的朋友可以参考下
    2023-07-07
  • Java 方法递归的思路详解

    Java 方法递归的思路详解

    程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。但是如果没终止条件会造成死循环,所以递归代码里要有结束自调自的条件,接下来讲解一下学习递归的思路
    2022-04-04

最新评论