今天就跟大家聊聊有關(guān)Mybatis框架的作用有哪些,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
我們提供的服務(wù)有:成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、昌江ssl等。為千余家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的昌江網(wǎng)站制作公司
mybatis基本架構(gòu)
mybatis的源碼應(yīng)該算是比較容易閱讀的,首先mybatis核心功能就是執(zhí)行Sql語(yǔ)句,但在其基礎(chǔ)上又有許多增強(qiáng)的地方(動(dòng)態(tài)Sql,ORM等)??匆粋€(gè)框架的時(shí)候,第一步是對(duì)整個(gè)框架有一個(gè)大體的了解。例如mybatis,我們可以從初始化到完成一個(gè)sql請(qǐng)求為主線,看一下涉及了哪些類(lèi)。我個(gè)人總結(jié)了一下,mybatis的框架主要的核心類(lèi)有4個(gè)
Configuration
Configuration就是用于解析、保存、處理Mybatis的配置內(nèi)容,包括了
mybatis基本配置,例如支持?jǐn)?shù)據(jù)庫(kù)中的字段支持下標(biāo)轉(zhuǎn)駝峰mapUnderscoreToCamelCase=true等等,參看Mybatis配置說(shuō)明
SqlMapper管理,也就是通過(guò)xml或者注解寫(xiě)的一些sql映射。相關(guān)的類(lèi)可以查看源碼中MappedStatement類(lèi)。
創(chuàng)建類(lèi),Configuration還有一些創(chuàng)建類(lèi)的功能,例如Executor、StatementHandler。這個(gè)2個(gè)類(lèi)后面還會(huì)說(shuō)到
小節(jié)Configuration
總結(jié)Configuration的功能,當(dāng)然,如何讀取和解析相關(guān)文件是Configuration中大部分代碼做的事。這些都是為了準(zhǔn)備后面mybatis運(yùn)行的基本條件。Configuration中創(chuàng)建類(lèi)是因?yàn)閯?chuàng)建的這些類(lèi)都依賴于Configuration(但這樣做數(shù)據(jù)和邏輯沒(méi)有做到分離)。
SqlSession
SqlSession可能是mybatis中我們最常用的類(lèi),其實(shí)他是一個(gè)門(mén)面類(lèi),直接對(duì)外提供服務(wù)
public interface SqlSession extends Closeable { <T> T selectOne(String statement); <E> List<E> selectList(String statement, Object parameter); int delete(String statement); void rollback(); void commit(); ... }
這些方法都是直接提供給外部調(diào)用的??吹竭@些方法是不是很親切。(我個(gè)人在看源碼的時(shí)候看到一些自己用過(guò)的一些類(lèi)或方法的時(shí)候都有種莫名的親近感。感覺(jué)終于和我的認(rèn)知世界有交集了)
SqlSession的創(chuàng)建
SqlSessionFactor是用于創(chuàng)建SqlSession建造者,提供給外部快速創(chuàng)建一個(gè)SqlSession。是一個(gè)工廠類(lèi),而SqlSessionFactor的創(chuàng)建則是由SqlSessionFactorBuilder。
Executor
前面說(shuō)了SqlSession只是一個(gè)門(mén)面類(lèi),Executor才是負(fù)責(zé)Sql語(yǔ)句執(zhí)行的。因此Executor才是整個(gè)mybatis核心。Executor的實(shí)現(xiàn)類(lèi)有
BaseExecutor:看名字知道是最基礎(chǔ)Executor,其他的Executor都和這個(gè)類(lèi)有一定的關(guān)系
CachingExecutor:每次查詢的時(shí)候會(huì)先從緩存中獲取,每次有增刪改的時(shí)候會(huì)讓緩存失效。CachingExecutor其實(shí)是一個(gè)代理內(nèi),內(nèi)部代理了BaseExecutor(或其子類(lèi))。在BaseExecutor基礎(chǔ)上增加了緩存操作。
相關(guān)類(lèi)
我們看一個(gè)Executor參數(shù)最多的一個(gè)方法
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;
這些類(lèi)都對(duì)執(zhí)行Sql有一定關(guān)系
MappedStatement
具體點(diǎn)來(lái)理解就是我們定義的Sql映射語(yǔ)句,例如我們xml定義的:
<select id="selectCountByPath" parameterType="java.lang.String" resultType="java.lang.Long"> select count(1) FROM config WHERE path = #{path} </select>
paramter
這個(gè)就是傳遞給sql映射的參數(shù),用于生成和填充動(dòng)態(tài)sql語(yǔ)句
RowBound
限定一次查詢數(shù)據(jù)量,類(lèi)很簡(jiǎn)單,看代碼就明白,不多說(shuō)
public class RowBounds { public static final int NO_ROW_OFFSET = 0; public static final int NO_ROW_LIMIT = Integer.MAX_VALUE; public static final RowBounds DEFAULT = new RowBounds(); private int offset; private int limit; public RowBounds() { this.offset = NO_ROW_OFFSET; this.limit = NO_ROW_LIMIT; } public RowBounds(int offset, int limit) { this.offset = offset; this.limit = limit; } }
ResultHandler
這個(gè)和本地緩存有關(guān),用于保存一個(gè)查詢語(yǔ)句的緩存對(duì)象,下次有相同的查詢語(yǔ)句的時(shí)候就會(huì)先嘗試從本地緩存中獲取。 注意:
,mybatis有2級(jí)緩存,第一級(jí)是CachingExecutor,第二級(jí)緩存就是mybatis的本地緩存,也就是和ResultHandler
緩存失效策略是和一級(jí)緩存一樣,任何增刪改都會(huì)清空本地緩存
CacheKey
一個(gè)查詢語(yǔ)句的在本地緩存中的key,根據(jù)sql語(yǔ)句,參數(shù)等等組成
BoundSql
這個(gè)對(duì)象就是本次實(shí)際需要執(zhí)行的sql語(yǔ)句有關(guān)的信息,
public class BoundSql { private String sql; private List<ParameterMapping> parameterMappings; private Object parameterObject; private Map<String, Object> additionalParameters; private MetaObject metaParameters; ...
如果說(shuō)parameter參數(shù)是實(shí)際傳入的參數(shù),那么BoundSql就是根據(jù)傳入?yún)?shù)進(jìn)行相關(guān)解析后的結(jié)果。他的創(chuàng)建在MappedStatement中,根據(jù)parameter和當(dāng)前執(zhí)行MappedStatement生成
public BoundSql getBoundSql(Object parameterObject) { BoundSql boundSql = sqlSource.getBoundSql(parameterObject); List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); if (parameterMappings == null || parameterMappings.isEmpty()) { boundSql = new BoundSql(configuration, boundSql.getSql(), parameterMap.getParameterMappings(), parameterObject); } // check for nested result maps in parameter mappings (issue #30) for (ParameterMapping pm : boundSql.getParameterMappings()) { String rmId = pm.getResultMapId(); if (rmId != null) { ResultMap rm = configuration.getResultMap(rmId); if (rm != null) { hasNestedResultMaps |= rm.hasNestedResultMaps(); } } } return boundSql; }
Interceptor
Mybatis提供了Interceptor用于在執(zhí)行Executor之前進(jìn)行一些操作,mybatis是怎么使用Interceptor。其實(shí)就是在創(chuàng)建Executor時(shí)候,會(huì)
public Executor newExecutor(Transaction transaction, ExecutorType executorType) { executorType = executorType == null ? defaultExecutorType : executorType; executorType = executorType == null ? ExecutorType.SIMPLE : executorType; Executor executor; if (ExecutorType.BATCH == executorType) { executor = new BatchExecutor(this, transaction); } else if (ExecutorType.REUSE == executorType) { executor = new ReuseExecutor(this, transaction); } else { executor = new SimpleExecutor(this, transaction); } if (cacheEnabled) { executor = new CachingExecutor(executor); } //看這里?。?! executor = (Executor) interceptorChain.pluginAll(executor); return executor; }
這里主要是通過(guò)jdk動(dòng)態(tài)代理實(shí)現(xiàn)的
public class Plugin implements InvocationHandler { ... public static Object wrap(Object target, Interceptor interceptor) { Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor); Class<?> type = target.getClass(); Class<?>[] interfaces = getAllInterfaces(type, signatureMap); if (interfaces.length > 0) { return Proxy.newProxyInstance( type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)); } return target; } ... @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { Set<Method> methods = signatureMap.get(method.getDeclaringClass()); if (methods != null && methods.contains(method)) { return interceptor.intercept(new Invocation(target, method, args)); } return method.invoke(target, args); } catch (Exception e) { throw ExceptionUtil.unwrapThrowable(e); } }
這樣在調(diào)用Executor的時(shí)候就會(huì)先判斷是否滿足Interceptor的執(zhí)行條件,滿足則會(huì)先執(zhí)行Intercepter#intercept()方法
最底層的Handler
要說(shuō)直接和Jdbc打交道的就是各種Handler類(lèi),例如
StatementHandler: 處理java.sql.Statement
ParameterHandler: 向PreparedStatement中設(shè)置參數(shù)
ResultSetHandler:處理sql執(zhí)行結(jié)果,并轉(zhuǎn)換成指定的類(lèi)對(duì)象 上面的這些其實(shí)都不復(fù)雜,所以代碼還是比較好理解的
Transaction
每個(gè)Executor生成的時(shí)候都會(huì)把Transaction傳入,在BaseExecutor中Transaction是其成員變量,那Transaction的作用是什么呢?
public interface Transaction { Connection getConnection() throws SQLException; void commit() throws SQLException; void rollback() throws SQLException; void close() throws SQLException; Integer getTimeout() throws SQLException; }
其實(shí)之前一直都沒(méi)提到過(guò)Connect誰(shuí)來(lái)管理,這里可以看出來(lái),Transaction負(fù)責(zé)了Connection的獲取,以及對(duì)這次Connect的提交和回滾等操作。這個(gè)類(lèi)也是比較好理解的。Executor的commit或者rollback最后都是調(diào)用Transaction的
看完上述內(nèi)容,你們對(duì)Mybatis框架的作用有哪些有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。
網(wǎng)頁(yè)名稱:Mybatis框架的作用有哪些
文章出自:http://jinyejixie.com/article36/jjiosg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、App設(shè)計(jì)、企業(yè)建站、網(wǎng)站維護(hù)、搜索引擎優(yōu)化、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)