Mybatis的动态Sql组合模式详情

作者:周杰伦本人??????? 时间:2021-12-26 03:26:35 

前言

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

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;
 }
}

来源:https://blog.51cto.com/u_15460453/5587848

标签:Mybatis,动态,Sql,组合,模式
0
投稿

猜你喜欢

  • 一文详解Reactor模型与实现示例

    2023-11-13 12:22:09
  • Java StringBuffer与StringBuilder有什么区别

    2022-12-15 22:35:12
  • 详谈Lock与synchronized 的区别

    2023-03-26 18:13:14
  • 基于Hadoop实现Knn算法

    2023-11-27 04:01:20
  • Java 如何实现时间控制

    2023-02-20 06:19:23
  • Java字符串split使用方法代码实例

    2023-02-06 18:55:31
  • C# TcpClient网络编程传输文件的示例

    2021-10-16 16:01:13
  • android同时控制EditText输入字符个数和禁止特殊字符输入的方法

    2021-08-01 14:16:46
  • Android重要控件SnackBar使用方法详解

    2022-11-10 04:49:41
  • c#批量抓取免费代理并且验证有效性的实战教程

    2023-12-19 23:33:30
  • 浅析C# 状态机Stateless

    2022-03-08 16:39:07
  • 详解Android Lint的原理及其使用

    2022-12-23 16:05:47
  • springboot相关面试题汇总详解

    2023-10-06 17:16:11
  • Android 数据库文件存取至储存卡的方法

    2023-05-08 19:12:14
  • Unity学习之FSM有限状态机

    2022-09-10 06:18:33
  • Android打开GPS导航并获取位置信息返回null解决方案

    2021-08-31 09:21:19
  • Jackson序列化和反序列化忽略字段操作

    2022-08-29 14:01:14
  • Mybatis-Plus字段策略FieldStrategy的使用

    2023-12-13 14:44:41
  • WinForm自定义函数FindControl实现按名称查找控件

    2021-09-23 17:27:25
  • ijkPlayer播放器的全自动编译脚本及最终编译包

    2023-01-10 13:52:18
  • asp之家 软件编程 m.aspxhome.com