Mybatis的動(dòng)態(tài)Sql組合模式詳情
前言
當(dāng)同一類型的很多對(duì)象組成一個(gè)樹(shù)結(jié)構(gòu)的時(shí)候,可以考慮使用組合模式,組合模式涉及三個(gè)類:
Component接口:定義樹(shù)的各個(gè)節(jié)點(diǎn)的一些操作
Left類:這個(gè)是樹(shù)的葉子結(jié)點(diǎn),實(shí)現(xiàn)Component接口,對(duì)于節(jié)點(diǎn)的管理它不去實(shí)現(xiàn),只實(shí)現(xiàn)業(yè)務(wù)邏輯
Composite類:這個(gè)是樹(shù)的非葉子節(jié)點(diǎn),實(shí)現(xiàn)Component接口,不但實(shí)現(xiàn)業(yè)務(wù)邏輯,同時(shí)會(huì)管理子節(jié)點(diǎn),會(huì)有個(gè)Component接口的集合類來(lái)管理子節(jié)點(diǎn)
Component角色
SqlNode就是扮演組合模式中的Component角色,Sql標(biāo)簽會(huì)解析成SqlNode對(duì)象,
public interface SqlNode { boolean apply(DynamicContext context); }
Composite角色
MixedSqlNode類扮演組合模式的Composite角色:
它也是解析<otherwise>
標(biāo)簽的類
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; } }
它有個(gè)SqlNode的集合類,記錄SqlNode對(duì)象,apply方法就是遍歷集合,依次調(diào)用自己的apply()方法
剩余其他SqlNode的實(shí)現(xiàn)類就充當(dāng)組合模式的Left類了:
Left類角色
TextSqlNode
TextSqlNode是包含${}的動(dòng)態(tài)sql片段,它的apply()方法的實(shí)現(xiàn):
@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); }
創(chuàng)建GenericTokenParser解析器,然后解析包含${}的sql片段,解析后保存到DynamicContext中
TrimSqlNode
TrimSqlNode是解析出的trim標(biāo)簽的對(duì)象,trim標(biāo)簽可以去除sql的and、逗號(hào)或者拼接where關(guān)鍵字等,
private final SqlNode contents; @Override public boolean apply(DynamicContext context) { FilteredDynamicContext filteredDynamicContext = new FilteredDynamicContext(context); boolean result = contents.apply(filteredDynamicContext); filteredDynamicContext.applyAll(); return result; }
先調(diào)用SqlNode 的apply方法 ,然后調(diào)用FilteredDynamicContext的applyAll()方法進(jìn)行前后綴的處理,F(xiàn)ilteredDynamicContext在DynamicContext包裝了一層,利用了裝飾者模式,除了DynamicContext的存儲(chǔ)解析結(jié)果和參數(shù)功能外還能進(jìn)行前后綴的處理
IfSqlNode
IfSqlNode是解析出if 標(biāo)簽、when標(biāo)簽的類,
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標(biāo)簽的test表達(dá)式,apply()方法中ExpressionEvaluator工具類解析test表達(dá)式,返回true之后調(diào)用具體SqlNode的apply()方法
StaticTextSqlNode
StaticTextSqlNode是非動(dòng)態(tài)的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; } }
總結(jié)
這篇文章從組合模式的角度分析了Mybatis動(dòng)態(tài)sql的部分,SqlNode是組合模式的Component接口,MixedSqlNode是組合模式的Composite角色,還有其他的SqlNode的實(shí)現(xiàn)類TextSqlNode、TrimSqlNode、IfSqlNode、StaticTextSqlNode,它們是解析不同的標(biāo)簽,TextSqlNode解析包含${}的動(dòng)態(tài)sql片段,TrimSqlNode類解析trim標(biāo)簽,IfSqlNode是解析出if 標(biāo)簽、when標(biāo)簽的類,StaticTextSqlNode是非動(dòng)態(tài)的sql片段
到此這篇關(guān)于Mybatis的動(dòng)態(tài)Sql組合模式詳情的文章就介紹到這了,更多相關(guān)Mybatis 組合模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis動(dòng)態(tài)SQL特性詳解
- Mybatis多表查詢與動(dòng)態(tài)SQL特性詳解
- MyBatis動(dòng)態(tài)sql查詢及多參數(shù)查詢方式
- Mybatis如何實(shí)現(xiàn)@Select等注解動(dòng)態(tài)組合SQL語(yǔ)句
- MyBatis?@Select注解介紹:基本用法與動(dòng)態(tài)SQL拼寫(xiě)方式
- MyBatis在注解上使用動(dòng)態(tài)SQL方式(@select使用if)
- Mybatis中xml的動(dòng)態(tài)sql實(shí)現(xiàn)示例
- MyBatis動(dòng)態(tài)SQL表達(dá)式詳解
相關(guān)文章
SpringDataMongoDB多文檔事務(wù)的實(shí)現(xiàn)
mongodb4.0也出來(lái)一段時(shí)間了,這個(gè)版本最為大眾期待的特性就是支持了多文檔事務(wù)。這篇文章主要介紹了SpringDataMongoDB多文檔事務(wù)的實(shí)現(xiàn),感興趣的小伙伴們可以參考一下2018-11-11支持SpEL表達(dá)式的自定義日志注解@SysLog介紹
這篇文章主要介紹了支持SpEL表達(dá)式的自定義日志注解@SysLog,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02使用SpringBoot注解方式處理事務(wù)回滾實(shí)現(xiàn)
這篇文章主要介紹了使用SpringBoot注解方式處理事務(wù)回滾實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08淺談?dòng)肧pringBoot實(shí)現(xiàn)策略模式
本文主要介紹了SpringBoot實(shí)現(xiàn)策略模式,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10RabbitMQ消息單獨(dú)與批量的TTL詳細(xì)介紹
這篇文章主要介紹了RabbitMQ消息單獨(dú)與批量的TTL,TTL全名是Time To Live存活時(shí)間,表示當(dāng)消息由生產(chǎn)端存入MQ當(dāng)中的存活時(shí)間,當(dāng)時(shí)間到達(dá)的時(shí)候還未被消息就會(huì)被自動(dòng)清除,感興趣的同學(xué)可以參考下文2023-05-05