<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      mybatis底層源碼

      一、運(yùn)行原理


      二、配置文件的解析以及創(chuàng)建SqlSessionFactory


      首先通過配置文件的文件流創(chuàng)建SqlSessionFactoryBuilder對象

      調(diào)用build方法,傳入文件流

      之后通過解析器解析xml配置文件

      通過XPathParse解析configuration節(jié)點(diǎn),獲取根節(jié)點(diǎn),之后再parseConfiguration()方法中根據(jù)根節(jié)點(diǎn)解析根節(jié)點(diǎn)中的每一個(gè)節(jié)點(diǎn)

      之后來到settingsElement()方法中

      environmentsElement(root.evalNode("environments"))獲取數(shù)據(jù)源配置被放到了Configuration里面

      解析mappers.xml配置文件

      兩種方式

      我們看看配置文件里面mappers標(biāo)簽是怎么配置的,官方給出了四種配置方式:

      1、Mapper.xml文件的相對路徑引用(解析XML獲取SQL)

      2、Mapper.xml文件的絕對路徑引用(解析XML獲取SQL)

      3、Mapper.java類文件的完全限定類名(解析注解獲取SQL)

      4、Mapper.java類文件所在的包路徑(解析注解獲取SQL)

      既然配置有4種配置方法,那對應(yīng)的解析的時(shí)候也有4種解析方法:


      XMLConfigBuilder.mapperElement

      XMLMapperBuilder.parse()獲取mapper配置節(jié)點(diǎn)

      解析mapper文件中的節(jié)點(diǎn)

      之后調(diào)用XbuildStatementFromContext()方法,對所有的crud配置節(jié)點(diǎn),進(jìn)行解析

      循環(huán)解析所有crud節(jié)點(diǎn)

      解析并獲取所有crud節(jié)點(diǎn)的屬性

      最后將所有的屬性值加入到一個(gè)MappedStatement中,封裝成MappedStatement,所以每一個(gè)MappedStatement表示一個(gè)crud的SQL語句詳細(xì)信息

      然后將每一個(gè)MappedStatement添加到MappedStatements集合中,最后加入configuration,到此,configuration就填充完畢,其中保存了所有的配置信息(全局配置文件及sql映射文件)

      通過configuration創(chuàng)建DefaultSqlSessionFactory

      總結(jié):就是將所有的配置文件信息保存在configuration中,通過configuration對象創(chuàng)建SqlSessionFactory


      三、SqlSession對象的創(chuàng)建


      通過SqlSessionFactoryopenSession獲取sqlSession

      首先通過configuration.getDefaultExecutorType()獲取執(zhí)行器類型,默認(rèn)為SIMPLE

      之后又來到openSessionFromDataSource()方法

      創(chuàng)建了一個(gè)Executor對象,來到newExecutor()方法

      Executor是一個(gè)接口,用來執(zhí)行crud

      是否配置了二級緩存,如果配置了使用CachingExecutor對Executor包裝,實(shí)際執(zhí)行crud還是Executor

      包裝后的Executor在查詢之前會(huì)有緩存操作,Executor創(chuàng)建完畢后

      會(huì)調(diào)用連接器鏈對executor進(jìn)行一個(gè)拼裝

      循環(huán)所有的攔截器重新包裝Executor,并返回

      將創(chuàng)建好的Executor對象傳入DefaultSqlSession中,DefaultSqlSession是SQLSession的實(shí)現(xiàn)類,


      可以看出DefaultSqlSession中也包含了全局配置文件configuration的數(shù)據(jù),最終執(zhí)行crud還是Executor


      總結(jié):創(chuàng)建Executor對象及DefaultSqlSession對象,注意如果有二級緩存會(huì)包裝Executor,其中還會(huì)使用攔截器鏈包裝Executor


      四、獲取Mapper的代理對象


      通過getMapper獲取mapper

      最終調(diào)用configuration的getMapper方法

      又調(diào)用mapperRegistrygetMapper方法

      mapperRegistry中保存了每一個(gè)mapper對應(yīng)的MapperProxyFactory

      根據(jù)接口類型獲取mapperProxyFactory,通過mapperProxyFactory創(chuàng)建代理對象

      首先創(chuàng)建一個(gè)mapperProxy對象,在調(diào)用newInstance方法

      MapperProxy實(shí)現(xiàn)InvocationHandler接口,這個(gè)是JDK做動(dòng)態(tài)代理需要傳入的對象

      之后就是通過JDK代理創(chuàng)建代理對象并返回,代理對象中包含了sqlSession,可以用來執(zhí)行crud


      總結(jié):mapperProxyFactory在configuration初始化完畢后,一個(gè)mapper就綁定一個(gè)mapperProxyFactory


      通過mapperProxyFactory創(chuàng)建mapperProxy代理對象,代理對象中保存sqlSession對象,sqlSession中包含類Executor對象,用來執(zhí)行crud


      五、代理對象執(zhí)行增刪改查


      調(diào)用代理的目標(biāo)方法時(shí),會(huì)先執(zhí)行invoke()方法

      先判斷執(zhí)行的方法是否是Object中的方法,否則就將方法包裝為一個(gè)MapperMethod,最后執(zhí)行其execute方法,傳入sqlSession及方法參數(shù)

      判斷sql語句的類型,我這里是查詢

      我這里返回對象進(jìn)入else流程,convertArgsToSqlCommandParam在解析參數(shù),單個(gè)參數(shù)直接返回,多個(gè)參數(shù)返回一個(gè)map,之后調(diào)用SqlSession的selectOne方法

      調(diào)用selectList查詢多個(gè)方法

      configuration中通過方法id獲取MappedStatement(就是configuration初始化時(shí)用來執(zhí)行crud的),之后調(diào)用executor的query方法,


      wrapCollection(parameter)是根據(jù)參數(shù)將其包裝為一個(gè)map,map中存放數(shù)據(jù)

      現(xiàn)獲取綁定的sql

      BoundSql中封裝了所有的sql信息,包括sql語句,參數(shù),參數(shù)映射關(guān)系,之后就是創(chuàng)建二級緩存中保存的key,之后就調(diào)用query方法

      如果配置二級緩存先獲取緩存,之后調(diào)用query方法,就是SimpleExecutor的query方法

      先從一級緩存中查詢獲取,這就印證了mybatis先查詢二級緩存,在查詢一級緩存,如果一級緩存中也沒有就執(zhí)行queryFromDatabase方法

      調(diào)用doQuery()查詢數(shù)據(jù),查詢出數(shù)據(jù)后又加入到本地緩存中

      首先聲明一個(gè)Statement對象,原生JDBC對象,在獲取configuration,在通過newStatementHandler創(chuàng)建StatementHandler對象,StatementHandler可以創(chuàng)建出Statement對象

      首先創(chuàng)建一個(gè) RoutingStatementHandler

      根據(jù)配置創(chuàng)建不同的Statement,默認(rèn)PREPARED,所以創(chuàng)建出一個(gè)PreparedStatementHandler,保存在RoutingStatementHandler中,


      之后又將statementHandler包裝在攔截器鏈中,之后調(diào)用prepareStatement(handler, ms.getStatementLog())方法創(chuàng)建Statement

      在prepareStatement中有對參數(shù)進(jìn)行預(yù)編譯

      調(diào)用parameterHandler進(jìn)行參數(shù)預(yù)編譯設(shè)置參數(shù),創(chuàng)建PreparedStatementHandler對象時(shí)創(chuàng)建parameterHandlerresultSetHandler,在創(chuàng)建這兩個(gè)對象時(shí),


      又將其包裝到攔截器鏈中,至此mybatis的四大對象(Executor,StatementHandler,parameterHandler,resultSetHandler)就全部創(chuàng)建完畢,調(diào)用setParameters設(shè)置參數(shù)

      調(diào)用TypeHandler給sql語句預(yù)編譯設(shè)置參數(shù),參數(shù)設(shè)置完畢就調(diào)用handler.query(stmt, resultHandler)執(zhí)行查詢

      通過resultSetHandler處理結(jié)果

      最后通過typeHandler.getResult(rs, column)返回結(jié)果


      總結(jié):先通過代理mapper對象,實(shí)際執(zhí)行crud是使用sqlSession,sqlSession又是使用executor執(zhí)行的,executor在執(zhí)行crud時(shí),


      會(huì)創(chuàng)建StatementHandler,StatementHandler就是用來處理(預(yù)編譯,設(shè)置參數(shù)等)sql語句,


      StatementHandler創(chuàng)建時(shí)創(chuàng)建了parameterHandler及resultSetHandler,


      parameterHandler設(shè)置參數(shù)等等工作,并且執(zhí)行sql語句,


      resultSetHandler是用來處理查詢后的結(jié)果,


      parameterHandler及resultSetHandler執(zhí)行時(shí)都會(huì)有一個(gè)TypeHandler做設(shè)置參數(shù)及獲取結(jié)果映射為javaBean,TypeHandler底層是使用JDBC操作的


      六、運(yùn)行流程總結(jié)

      • 根據(jù)配置文件(全局文件及sql映射文件)初始化出Configuration

      • 創(chuàng)建DefaultSqlSession對象,其中包括Configuration及Executor(根據(jù)全局配置文件中的defaultExecutorType進(jìn)行初始化)

      • DefaultSqlSession或Mapper接口對應(yīng)的MapperProxy,MapperProxy包含DefaultSqlSession

      • 執(zhí)行增刪改查方法,代理對象調(diào)用DefaultSqlSession(Executor)的CRUD,創(chuàng)建一個(gè)Statement對象,同時(shí)創(chuàng)建StatementHandler,創(chuàng)建StatementHandler同時(shí)也會(huì)創(chuàng)建出parameterHandler及resultSetHandler,調(diào)用StatementHandler(parameterHandler)的預(yù)編譯參數(shù)及設(shè)置參數(shù)值,在調(diào)用StatementHandler的CRUD方法,使用resultSetHandler封裝結(jié)果

      • 四大對象每個(gè)創(chuàng)建時(shí)都有一個(gè)攔截器鏈的步驟,這一步在mybatis的插件中有用。

      posted @ 2025-03-26 21:07  jock_javaEE  閱讀(21)  評論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 久久久久久伊人高潮影院| 国产91久久精品成人看| 翘臀少妇被扒开屁股日出水爆乳| 美女扒开奶罩露出奶头视频网站| 亚洲aⅴ男人的天堂在线观看| 日韩中文字幕综合第二页| 激情综合网激情国产av| 四虎成人在线观看免费| 九九色这里只有精品国产| 亚洲欧美日韩综合久久久| 久久久亚洲欧洲日产国码αv| 国产精品视频免费一区二区三区| 亚洲女同在线播放一区二区 | 国产精品日日摸夜夜添夜夜添无码| 99久久婷婷国产综合精品青草漫画| 国产亚洲欧美另类一区二区| 汝城县| 九九热在线视频免费观看| 国产91午夜福利精品| 日本边添边摸边做边爱的网站| 色综合天天综合网天天看片| 免费a级黄毛片| 亚洲精品理论电影在线观看| 女人香蕉久久毛毛片精品| 日韩精品成人一区二区三| 欧美亚洲一区二区三区在线| 女同另类激情在线三区| 九九热在线免费视频播放| 草草浮力影院| 精品国产美女av久久久久| 日日噜久久人妻一区二区| 亚洲AV无码不卡在线播放| 人妻在线无码一区二区三区| 成人精品老熟妇一区二区| 国产欧美精品一区二区三区-老狼| av偷拍亚洲一区二区三区 | 久久久久久久一线毛片| 成人av午夜在线观看| 深夜福利啪啪片| 国产激情艳情在线看视频| 亚洲色一色噜一噜噜噜|