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<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 組合模式內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Mybatis 實現動態組裝查詢條件,仿SQL模式
- java合成模式之神奇的樹結構
- Java結構型設計模式之組合模式詳解
- Mybatis #foreach中相同的變量名導致值覆蓋的問題解決
- Java設計模式之組合模式的示例詳解