聊聊Mybatis的动态Sql之组合模式

网友投稿 953 2022-10-17

聊聊Mybatis的动态Sql之组合模式

聊聊Mybatis的动态Sql之组合模式

@[TOC]

聊聊Mybatis的动态Sql之组合模式

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

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 contents; public MixedSqlNode(List 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片段

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:FinClip:什么是小程序运行时以及它将如何颠覆传统App?
下一篇:数字化时代App们将何去何从?
相关文章

 发表评论

暂时没有评论,来抢沙发吧~