第4章 SqlSession中四大神器之Executor(執(zhí)行器)
4.1 Executor簡介
每一個SqlSession對象都會擁有一個Executor(執(zhí)行器對象);這個執(zhí)行對象負(fù)責(zé)[增刪改查]的具體操作.我們可以簡單的將它理解為JDBC中Statement的封裝版.
4.2 Executor繼承結(jié)構(gòu)
Executor是一個接口;主要有兩個實現(xiàn)類.分別是[BaseExecutor]和[CachingExecutor].
[BaseExecutor]是一個抽象類.這種通過抽象類實現(xiàn)接口的方式是[適配器設(shè)計模式]的體現(xiàn).
主要用于方便次一級子類對接口中方法的實現(xiàn).
[BaseExecutor]主要有三個實現(xiàn)類[SimpleExecutor],[ ReuseExecutor],[ BatchExecutor]
[SimpleExecutor]被稱為[簡單執(zhí)行器],是MyBatis中默認(rèn)使用的執(zhí)行器. 每執(zhí)行一次update或select忠蝗,就開啟一個Statement對象,用完立刻關(guān)閉Statement對象。(可以是Statement或PrepareStatement對象)
[ ReuseExecutor]被稱為[可重用執(zhí)行器].這里的重用指的是重復(fù)使用Statement. 它會在內(nèi)部利用一個Map把創(chuàng)建的Statement都緩存起來棒掠,每次在執(zhí)行一條SQL語句時闷愤,它都會去判斷之前是否存在基于該SQL緩存的Statement對象岗照,存在而且之前緩存的Statement對象對應(yīng)的Connection還沒有關(guān)閉的時候就繼續(xù)用之前的Statement對象摆尝,否則將創(chuàng)建一個新的Statement對象多艇,并將其緩存起來逻恐。因為每一個新的SqlSession都有一個新的Executor對象,所以我們緩存在ReuseExecutor上的Statement的作用域是同一個SqlSession
[ BatchExecutor]稱為[批處理執(zhí)行器].用于將多個sql語句一次性輸送到數(shù)據(jù)庫執(zhí)行.
[CachingExecutor]稱為[緩存執(zhí)行器]. 先從緩存中獲取查詢結(jié)果,存在就返回复隆,不存在拨匆,再委托給Executor delegate去數(shù)據(jù)庫取,delegate可以是上面任一的SimpleExecutor挽拂、ReuseExecutor惭每、BatchExecutor。代碼如下:
4.3 Excecutor對象創(chuàng)建
執(zhí)行器對象是由Coniguration對象負(fù)責(zé)創(chuàng)建的.Configuration對象會根據(jù)得到[ExecutorType]創(chuàng)建對應(yīng)的Excecutor對象,并把這個Excecutor對象傳給SqlSession對象
4.4 ExcecutorType的選擇.
ExecutorType來決定Configuration對象創(chuàng)建何種類型的執(zhí)行器.它的賦值可以通過兩個地方進行賦值.
首先.可以通過<settings>標(biāo)簽來設(shè)置當(dāng)前工程中所有SqlSession對象使用的默認(rèn)Executour
也可以通過SqlSessoinFactory中openSession方法來指定具體的SqlSession使用的執(zhí)行器
第5章 SqlSession中四大神器之StatementHandler
5.1 StatementHandler簡介
是四大神器中最重要的一個對象,負(fù)責(zé)操作Statement與數(shù)據(jù)庫進行交流.在工作時
還會使用ParameterHandler進行參數(shù)配置,使用ResultHandler將查詢結(jié)果與實體類對象進行綁定.
首先看一下StatementHandler接口定義
在StatementHandler接口中有四種重要的方法.分別是prepare,parameterize,batch,update.
prepare:用于具體創(chuàng)建一個Statement對象或則preparedStatement對象
parameterize:用于初始化Statement及對Sql中占位符進行賦值.
update:用于通知Statement將[insert,update,delete]推送到數(shù)據(jù)庫
query:用于通知Statement將[select]推送到數(shù)據(jù)庫并返回對應(yīng)查詢結(jié)果.
5.2 StatementHandler繼承結(jié)構(gòu)
從上圖可以看到StatementHandler接口下有兩個直接實現(xiàn)類BaseStatementHandler和[RoutingStatementHandler]
[]RoutingStatementHandler]:是一個具體實現(xiàn)類.在這個類中并沒有對Statement對象進行具體使用.只是根據(jù)得到Executor類型,決定創(chuàng)建何種類型StatementHandler對象.在MyBatis工作時,使用的StatementHandler接口對象實際上就是RoutingStatementHandler對象.
我們可以簡單理解為
StatementHandler statmentHandler = new RountingStatementHandler();
在RountingStatementHandler創(chuàng)建時,就跟根據(jù)接收的Executor類型來創(chuàng)建這個三個類型對象的.
5.3 StatementHandler對象創(chuàng)建
StatementHandler對象是在SqlSession對象接收到操作命令時,由Configuraion中newStatementHandler方法負(fù)責(zé)調(diào)用的.
RoutingStatementHandler構(gòu)造方法,將會根據(jù)Executor的類型決定創(chuàng)建SimpleStatementHandler,PreparedStatementHandler,CallableStatementHandler實例對象.
5.4 StatementHandler接口方法介紹
(1) prepare方法:
prepare方法用于創(chuàng)建一個(Statement or PreparedStatement or CallableStatement)對象,并設(shè)置Statement對象的最大工作時間和一次性讀取的最大數(shù)據(jù)量.讓后將生成的Statement對象返回.
prepare方法只在BaseStatementHandler被實現(xiàn).在其三個子類中沒有被重寫.用于三個子類調(diào)用獲得對應(yīng)的Statement接口對象.
prepare方法依靠instantiateStatement(connection)方法來返回具體Statement接口對象.
這個方法是BaseStatementHandler中定義的抽象方法,由三個子類來具體實現(xiàn).
SimpleHandler中的[instantiateStatement] 方法
PreparedStatementHandler中的[instantiateStatement] 方法
CallableStatementHandler中的[instantiateStatement] 方法
(2) parameterize方法
主要為PreparedStatement和CallableStatement傳參.因此只在PreparedStatementHandler和CallableStatementHandler中被重寫
PreparedStatementHandler中的parameterize
CallableStatementHandler中的parameterize
在這兩個方法中,可以看到都是[ParameterHandler]對象進行參數(shù)賦值的.
(3) query方法
輸送查詢查詢語句,并將查詢結(jié)果轉(zhuǎn)換對應(yīng)的實體類對象
SimpleStatementHandler 中的 query 方法
PreparedStatementHandler中的query方法
CallableStatementHandler中的query方法
可以看到在得到查詢結(jié)果后,都是使用[ResultSetHandler]對結(jié)果進行轉(zhuǎn)換.
(4) update方法
輸送[insert,update,delete]語句并返回處理數(shù)據(jù)行
SimpleStatementHandler中的update方法
PreparedStatementHandler中update方法
CallableStatementHandler中update方法
第6章 SqlSession中四大神器之ParameterHandler
6.1 ParameterHandler簡介
參數(shù)處理器,負(fù)責(zé)為PreparedStatement的sql語句參數(shù)動態(tài)賦值
這個接口中只有兩個方法
getParameterObject 方法,用于讀取參數(shù).
setParameters用于對PreparedStatement的參數(shù)賦值.
6.2 ParameterHandler繼承結(jié)構(gòu)
只有一個實現(xiàn)類DefaultParameterHandler
6.3 ParameterHandler對象創(chuàng)建
參數(shù)處理器對象是在創(chuàng)建StatementHandler對象同時被創(chuàng)建的.由Configuration對象負(fù)責(zé)創(chuàng)建.
創(chuàng)建時 傳入三個對象:執(zhí)行SQL對應(yīng)的配置信息MappedStatement亏栈、參數(shù)對象Object台腥,SQL的BoundSql。
注:一個BoundSql對象仑扑,代表了一次sql語句的實際執(zhí)行览爵,而SqlSource對象的責(zé)任置鼻,就是根據(jù)傳入的參數(shù)對象镇饮,動態(tài)計算出這個BoundSql,也就是說Mapper文件中的節(jié)點的計算箕母,是由SqlSource對象完成的储藐。SqlSource最常用的實現(xiàn)類是DynamicSqlSource
6.4 ParameterHandler中的參數(shù)從何而來.
上述命令的實參10是如何添加到對應(yīng)的SQL語句中的.
在mybatis中,使用動態(tài)代理模式.當(dāng)dao.findByDeptNo(10)將要執(zhí)行時;會被JVM進行攔截
交給mybatis中的代理實現(xiàn)類MapperProxy的invoke方法中
然后在一步步交給ParameterHandler中setParameter方法,將參數(shù)交給對應(yīng)占位符
6.5 ParameterHandler中
第7章 SqlSession中四大神器之ResultSetHandler
7.1 ResultSetHandler簡介
ResultSetHandler接口主要負(fù)責(zé)兩件事
(1) 處理Statement執(zhí)行后產(chǎn)生的結(jié)果集,生成結(jié)果列表
(2) 處理存儲過程執(zhí)行后的輸出參數(shù)
7.2 ResultSetHandler繼承結(jié)構(gòu)
只有一個實現(xiàn)類DefaultResultSetHandler