?我們接著上一篇Mybatis(3),我們來(lái)看看上面獲取Mapper的過(guò)程:
我們從mybatis主要構(gòu)件的執(zhí)行流程:

接下來(lái)我們來(lái)看看SqlSession是什么獲取Mapper的:
AccountMapper mapper = sqlSession.getMapper(AccountMapper.class);
接著看看getMapper:
public <T> T getMapper(Class<T> type) {
//configuration上下文中根據(jù)Class類(lèi)型來(lái)查找
return configuration.<T>getMapper(type, this);
}
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
//從mapperRegistry中獲取mapper代理
return mapperRegistry.getMapper(type, sqlSession);
}
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
//獲取生產(chǎn)mapper代理的的MapperProxyFactory
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {
//真正創(chuàng)建代理mapper的的地方
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
//創(chuàng)建mapper代理
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
//創(chuàng)建mapper代理
protected T newInstance(MapperProxy<T> mapperProxy) {
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
這里我們就可以很明白的看出,Mybatis中為什么只有Mapper接口便能夠運(yùn)行SQL?
答:因?yàn)橛成淦鞯腦ML文件的命名空間對(duì)應(yīng)的就是Mapper接口的全路勁,那么根據(jù)全路徑和方法名便能夠綁定起來(lái),通過(guò)代理技術(shù),為接口提供代理類(lèi),使接口跑起來(lái),而后采用命令模式,最后是使用SqlSession接口的方法使的它能夠執(zhí)行查詢。
這里我們可以理解SQL Mapper:是由一個(gè)Java接口和XML文件(注解)構(gòu)成的
最后我們來(lái)看看Mapper映射器內(nèi)部組成:
1、MappedStatement:保存映射器的一個(gè)節(jié)點(diǎn)。包括許多我們配置的SQL,Sql的id、緩存信息、resultMap、parameterType、resultType、languageDriver
2、SqlSource:它提供BoundSql對(duì)象的地方,它是MappedStatement的一個(gè)屬性。主要作用根據(jù)參數(shù)和其他規(guī)則組裝SQL
3、 BoundSql:它是建立SQL和參數(shù)的地方。它有3個(gè)常用的屬性:SQL、parameterObject、parameterMappings
BoundSql:
目的:在插件中往往需要拿到BoundSql:獲取運(yùn)行的SQL和參數(shù)以及參數(shù)規(guī)則,做出適當(dāng)?shù)男薷?,?lái)滿足我們的特殊需要
BoundSql的3個(gè)屬性:parameterMappings、parameterObject和sql
? parameterObject:參數(shù)本身
? sql:就是我們書(shū)寫(xiě)在映射器里面的一條SQL,在插件的情況下,我們可以根據(jù)需要進(jìn)行改寫(xiě)。
? parameterMappings:它是一個(gè)List<ParameterMapping>,ParameterMapping的對(duì)象描述的是參數(shù)。包括:參數(shù)的屬性、名稱、表達(dá)式、javaType、jdbcType、typeHandler等重要信息。通過(guò)它可以實(shí)現(xiàn)參數(shù)和SQL的結(jié)合,以便PreparedStatement能夠通過(guò)它找到parameterObject對(duì)象的屬性并設(shè)置參數(shù),使程序準(zhǔn)確的執(zhí)行。