mybatis源碼解讀之executor包語(yǔ)句處理功能
1.mybatis對(duì)多語(yǔ)句類(lèi)型的支持
在mybatis
映射文件中傳參數(shù),主要用到#{} 或者 ${}.
#{}:表示使用這種符號(hào)的變量會(huì)以預(yù)編譯的形式賦值到sql片段中。
${}:表示使用這種符號(hào)的變量會(huì)以字符串的形式直接插到sql片段中。
mybatis中支持三種語(yǔ)句類(lèi)型,不同語(yǔ)句類(lèi)型支持的變量符號(hào)不同。mybatis的三種類(lèi)型如下:
STATEMENT
:這種語(yǔ)句類(lèi)型中,只會(huì)對(duì)sql片段進(jìn)行簡(jiǎn)單的字符串拼接。只支持使用${}.PREPARED
:這種語(yǔ)句中會(huì)先對(duì)sql片段進(jìn)行字符串拼接,然后再對(duì)sql片段進(jìn)行賦值??梢允褂?{}和${}.CALLABLE
:這種語(yǔ)句用了實(shí)現(xiàn)執(zhí)行過(guò)程的調(diào)用,會(huì)先對(duì)sql片段進(jìn)行字符串拼接,然后對(duì)sql片段進(jìn)行賦值。可以使用#{}和${}.
2.mybatis的語(yǔ)句處理功能
statement
子包負(fù)責(zé)提供語(yǔ)句處理功能,其中StatementHandler
是語(yǔ)句功能類(lèi)的父接口,RoutingStatementHandler
類(lèi)是一個(gè)代理類(lèi),它能夠根據(jù)傳入的MappedStatement
對(duì)象的具體類(lèi)型選中一個(gè)具體的被代理對(duì)象,然后將所有實(shí)際操作都委托給被代理對(duì)象。所以RoutingStatementHandler類(lèi)提供的是路由功能,而路由選擇的依據(jù)就是語(yǔ)句類(lèi)型。
public class RoutingStatementHandler implements StatementHandler { ? // 根據(jù)語(yǔ)句類(lèi)型選取出的被代理類(lèi)的對(duì)象 ? private final StatementHandler delegate; ? public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { ? ? // 根據(jù)語(yǔ)句類(lèi)型選擇被代理對(duì)象 ? ? switch (ms.getStatementType()) { ? ? ? case STATEMENT: ? ? ? ? delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); ? ? ? ? break; ? ? ? case PREPARED: ? ? ? ? delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); ? ? ? ? break; ? ? ? case CALLABLE: ? ? ? ? delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); ? ? ? ? break; ? ? ? default: ? ? ? ? throw new ExecutorException("Unknown statement type: " + ms.getStatementType()); ? ? } ? } }
BaseStatementHandler
作為三個(gè)實(shí)現(xiàn)類(lèi)的父類(lèi),提供了實(shí)現(xiàn)類(lèi)的公共方法。并且BaseStatementHandler
類(lèi)使用的模板模式在prepare
方法中定義了整個(gè)方法的框架,然后將一些與子類(lèi)相關(guān)的操作交給三個(gè)子類(lèi)處理。
SimpleStatementHandler
類(lèi)、PreparedStatementHandler
類(lèi)和CallableStatementHandler
類(lèi)是三個(gè)真正的statement
處理器,分別處理statement、preparedStatement
、CallableStatement
對(duì)象。通過(guò)其中的parameterize
方法可以看出三個(gè)Statement
處理器的不同。
SimpleStatementHandler
中parameterize
方法的實(shí)現(xiàn)為空,因?yàn)樗恍枰瓿勺址鎿Q即可,不需要進(jìn)行參數(shù)處理
public class SimpleStatementHandler extends BaseStatementHandler { ?@Override ? public void parameterize(Statement statement) { ? ? // N/A ? } ? }
PreparedStatementHandler
中parameterize
方法最終通過(guò)ParameterHandler接口經(jīng)過(guò)多級(jí)中轉(zhuǎn)后調(diào)用了PreparedStatement類(lèi)中的參數(shù)賦值方法。
public class PreparedStatementHandler extends BaseStatementHandler { ? @Override ? public void parameterize(Statement statement) throws SQLException { ? ? parameterHandler.setParameters((PreparedStatement) statement); ? } }
CallableStatementHandler
中parameterize主要是通過(guò)registerOutputParameters方法中轉(zhuǎn)后調(diào)用CallableStatement中的輸出參數(shù)注冊(cè)方法完成輸出參數(shù)的注冊(cè),然后通過(guò)ParameterHandler接口經(jīng)過(guò)多級(jí)中轉(zhuǎn)后調(diào)用了PreparedStatement類(lèi)中的參數(shù)賦值方法。
public class CallableStatementHandler extends BaseStatementHandler { ?/** ? ?* 對(duì)語(yǔ)句進(jìn)行參數(shù)處理 ? ?* @param statement SQL語(yǔ)句 ? ?* @throws SQLException ? ?*/ ? @Override ? public void parameterize(Statement statement) throws SQLException { ? ? // 輸出參數(shù)的注冊(cè) ? ? registerOutputParameters((CallableStatement) statement); ? ? // 輸入?yún)?shù)的處理 ? ? parameterHandler.setParameters((CallableStatement) statement); ? } }
到此這篇關(guān)于 mybatis源碼解讀之executor包語(yǔ)句處理功能的文章就介紹到這了,更多相關(guān)executor包語(yǔ)句處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis綁定錯(cuò)誤提示BindingException:Invalid bound statement (not f
這篇文章主要介紹了MyBatis綁定錯(cuò)誤提示BindingException:Invalid bound statement (not found)的解決辦法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧2017-01-01Spring boot JPA實(shí)現(xiàn)分頁(yè)和枚舉轉(zhuǎn)換代碼示例
這篇文章主要介紹了Spring boot JPA實(shí)現(xiàn)分頁(yè)和枚舉轉(zhuǎn)換代碼示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09Java多線程之volatile關(guān)鍵字及內(nèi)存屏障實(shí)例解析
volatile是JVM提供的一種最輕量級(jí)的同步機(jī)制,因?yàn)镴ava內(nèi)存模型為volatile定義特殊的訪問(wèn)規(guī)則,使其可以實(shí)現(xiàn)Java內(nèi)存模型中的兩大特性:可見(jiàn)性和有序性。這篇文章主要介紹了Java多線程之volatile關(guān)鍵字及內(nèi)存屏障,需要的朋友可以參考下2019-05-05java正則表達(dá)式學(xué)習(xí)筆記之命名捕獲
這篇文章主要為大家詳細(xì)介紹了java正則表達(dá)式中的命名捕獲,感興趣的小伙伴們可以參考一下2016-02-02Spring?Mvc中CommonsMultipartFile的特性實(shí)例詳解
這篇文章主要給大家介紹了關(guān)于Spring?Mvc中CommonsMultipartFile特性的相關(guān)資料,SpringMVC擁有強(qiáng)大的靈活性,非侵入性和可配置性,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-11-11Druid(新版starter)在SpringBoot下的使用教程
Druid是Java語(yǔ)言中最好的數(shù)據(jù)庫(kù)連接池,Druid能夠提供強(qiáng)大的監(jiān)控和擴(kuò)展功能,DruidDataSource支持的數(shù)據(jù)庫(kù),這篇文章主要介紹了Druid(新版starter)在SpringBoot下的使用,需要的朋友可以參考下2023-05-05kafka?消息隊(duì)列中點(diǎn)對(duì)點(diǎn)與發(fā)布訂閱的區(qū)別說(shuō)明
這篇文章主要介紹了kafka?消息隊(duì)列中點(diǎn)對(duì)點(diǎn)與發(fā)布訂閱的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05springboot基于過(guò)濾器實(shí)現(xiàn)接口請(qǐng)求耗時(shí)統(tǒng)計(jì)操作
這篇文章主要介紹了springboot基于過(guò)濾器實(shí)現(xiàn)接口請(qǐng)求耗時(shí)統(tǒng)計(jì)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09