<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試難點(diǎn):Mybatis 中的 DAO 接口和 XML 文件里的 SQL 是如何建立關(guān)系的?

          共 2873字,需瀏覽 6分鐘

           ·

          2022-08-26 18:51

          一、解析XML:

          首先,Mybatis 在初始化 SqlSessionFactoryBean 時(shí),會(huì)找到 mapperLocations 配置的路徑下中所有的XML文件并進(jìn)行解析,這里我們重點(diǎn)關(guān)注兩部分:

          1、創(chuàng)建SqlSource:

          Mybatis會(huì)把每個(gè)SQL標(biāo)簽封裝成SqlSource對(duì)象,然后根據(jù)SQL語(yǔ)句的不同,又分為動(dòng)態(tài)SQL和靜態(tài)SQL。其中,靜態(tài)SQL包含一段String類型的sql語(yǔ)句;而動(dòng)態(tài)SQL則是由一個(gè)個(gè)SqlNode組成。

          假如我們有這樣一個(gè)SQL:

          <select id="getUserById" resultType="user">
              select * from user 
              <where>
                  <if test="uid!=null">
                      and uid=#{uid}
                  </if>
              </where>
          </select>    

          它對(duì)應(yīng)的SqlSource對(duì)象看起來應(yīng)該是這樣的:

          2、創(chuàng)建MappedStatement:

          接下來,Mybatis會(huì)為XML中的每個(gè)SQL標(biāo)簽都生成一個(gè)MappedStatement對(duì)象,這里面有兩個(gè)屬性很重要:

          • id:全限定類名+方法名組成的ID
          • sqlSource:當(dāng)前SQL標(biāo)簽對(duì)應(yīng)的SqlSource對(duì)象

          創(chuàng)建完的 MappedStatement 對(duì)象會(huì)被添加到 Configuration 中,Configuration對(duì)象就是Mybatis中的大管家,基本所有的配置信息都維護(hù)在這里。當(dāng)把所有的XML都解析完成之后,Configuration就包含了所有的SQL信息。

          到目前為止,XML就解析完成了,當(dāng)我們執(zhí)行Mybatis方法的時(shí)候,就可以通過 “全限定類名+方法名” 找到 MappedStatement 對(duì)象,然后解析里面的SQL內(nèi)容并進(jìn)行執(zhí)行即可。

          二、Dao接口代理:

          但是Dao接口并沒有具體的實(shí)現(xiàn)類,那么在被調(diào)用時(shí),最終又是怎樣找到我們的SQL語(yǔ)句的呢?

          首先,我們?cè)赟pring配置文件中,一般會(huì)這樣配置:

          <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
           <property name="basePackage" value="com.viewscenes.netsupervisor.dao" />
           <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
          </bean>

          或者你的項(xiàng)目是基于SpringBoot的,那么肯定也見過這種:@MapperScan("com.xxx.dao")

          它們的作用是一樣的,就是將包路徑下的所有類注冊(cè)到 Spring Bean 中,并將它們的beanClass設(shè)置為 MapperFactoryBean,MapperFactoryBean 實(shí)現(xiàn)了 FactoryBean 接口,俗稱工廠Bean。那么,當(dāng)我們通過 @Autowired 注入這個(gè)Dao接口時(shí),返回的對(duì)象就是 MapperFactoryBean 這個(gè)工廠Bean中的 getObject() 方法對(duì)象。

          那么,這個(gè)方法干了些什么呢?簡(jiǎn)單來說,它就是通過JDK動(dòng)態(tài)代理,返回了一個(gè)Dao接口的代理對(duì)象 MapperProxy,當(dāng)我們通過 @Autowired 注入Dao接口時(shí),注入的就是這個(gè)代理對(duì)象,我們調(diào)用 Dao接口中的方法時(shí),則會(huì)調(diào)用到 MapperProxy 對(duì)象的invoke()方法。

          那么,目前為止,我們通過Dao接口也有了代理實(shí)現(xiàn),所以就可以執(zhí)行到它里面的方法了。擴(kuò)展:最全的java面試題庫(kù)

          三、執(zhí)行:

          如上所述,當(dāng)我們調(diào)用Dao接口方法的時(shí)候,實(shí)際調(diào)用到代理對(duì)象的invoke()方法。在這里,實(shí)際上調(diào)用的就是SqlSession里面的東西了。

          public class DefaultSqlSession implements SqlSession {
           
           public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
            try {
             MappedStatement ms = configuration.getMappedStatement(statement);
             return executor.query(ms, 
              wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
            }
           }
          }

          看到以上代碼,說明我們想的不錯(cuò)。它就是通過statement(全限定類型+方法名)拿到MappedStatement 對(duì)象,然后通過執(zhí)行器Executor去執(zhí)行具體SQL并返回。

          四、總結(jié):

          1、針對(duì)Mybatis中的Dao接口和XML文件里的SQL是如何建立關(guān)系的問題,主要可以歸納為下面幾點(diǎn)小點(diǎn):

          • SqlSource以及動(dòng)態(tài)標(biāo)簽SqlNode
          • MappedStatement對(duì)象
          • Spring 工廠Bean 以及動(dòng)態(tài)代理
          • SqlSession以及執(zhí)行器

          2、針對(duì)有兩個(gè)XML文件和這個(gè)Dao建立關(guān)系是否會(huì)沖突的問題:不管有幾個(gè)XML和Dao建立關(guān)系,只要保證namespace+id唯一即可。


          來源:blog.csdn.net/a745233700/article/

          details/89308762


          瀏覽 44
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产黄a 国产自在 | 蜜芽无码AV | 色婷婷国产精品视频一区 | 欧美狠狠撸| 清纯唯美一区二区三区 |