面試難點(diǎn):Mybatis 中的 DAO 接口和 XML 文件里的 SQL 是如何建立關(guān)系的?
點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)
作者:張維鵬
一、解析XML:
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語句的不同,又分為動(dòng)態(tài)SQL和靜態(tài)SQL。其中,靜態(tài)SQL包含一段String類型的sql語句;而動(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> SqlSource對(duì)象看起來應(yīng)該是這樣的:
2、創(chuàng)建MappedStatement:
MappedStatement對(duì)象,這里面有兩個(gè)屬性很重要:id:全限定類名+方法名組成的ID sqlSource:當(dāng)前SQL標(biāo)簽對(duì)應(yīng)的SqlSource對(duì)象
MappedStatement對(duì)象會(huì)被添加到Configuration中,Configuration對(duì)象就是Mybatis中的大管家,基本所有的配置信息都維護(hù)在這里。當(dāng)把所有的XML都解析完成之后,Configuration就包含了所有的SQL信息。
全限定類名+方法名” 找到MappedStatement對(duì)象,然后解析里面的SQL內(nèi)容并進(jìn)行執(zhí)行即可。二、Dao接口代理:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.viewscenes.netsupervisor.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>@MapperScan("com.xxx.dao"),beanClass設(shè)置為MapperFactoryBean,MapperFactoryBean實(shí)現(xiàn)了FactoryBean接口,俗稱工廠Bean。那么,當(dāng)我們通過@Autowired注入這個(gè)Dao接口時(shí),返回的對(duì)象就是MapperFactoryBean這個(gè)工廠Bean中的getObject()方法對(duì)象。MapperProxy,當(dāng)我們通過@Autowired注入Dao接口時(shí),注入的就是這個(gè)代理對(duì)象,我們調(diào)用 Dao接口中的方法時(shí),則會(huì)調(diào)用到MapperProxy對(duì)象的invoke()方法。三、執(zhí)行:
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);
}
}
}statement(全限定類型+方法名)拿到MappedStatement對(duì)象,然后通過執(zhí)行器Executor去執(zhí)行具體SQL并返回。
四、總結(jié)
SqlSource以及動(dòng)態(tài)標(biāo)簽SqlNodeMappedStatement對(duì)象Spring工廠Bean以及動(dòng)態(tài)代理 SqlSession以及執(zhí)行器
namespace+id唯一即可。
往 期 推 薦
3、互聯(lián)網(wǎng)人為什么學(xué)不會(huì)擺爛
4、為什么國外JetBrains做 IDE 就可以養(yǎng)活自己,國內(nèi)不行?區(qū)別在哪?
點(diǎn)分享
點(diǎn)收藏
點(diǎn)點(diǎn)贊
點(diǎn)在看
評(píng)論
圖片
表情





