?我們接著上一篇Mybatis(3)膝迎,我們來看看上面獲取Mapper的過程:
我們從mybatis主要構(gòu)件的執(zhí)行流程:
接下來我們來看看SqlSession是什么獲取Mapper的:
AccountMapper mapper = sqlSession.getMapper(AccountMapper.class);
接著看看getMapper:
public <T> T getMapper(Class<T> type) {
//configuration上下文中根據(jù)Class類型來查找
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ù)全路徑和方法名便能夠綁定起來,通過代理技術(shù)蔚袍,為接口提供代理類撤嫩,使接口跑起來,而后采用命令模式鹉梨,最后是使用SqlSession接口的方法使的它能夠執(zhí)行查詢讳癌。
這里我們可以理解SQL Mapper:是由一個(gè)Java接口和XML文件(注解)構(gòu)成的
最后我們來看看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ù)男薷牟裙伲瑏頋M足我們的特殊需要
BoundSql的3個(gè)屬性:parameterMappings却桶、parameterObject和sql
? parameterObject:參數(shù)本身
? sql:就是我們書寫在映射器里面的一條SQL,在插件的情況下,我們可以根據(jù)需要進(jìn)行改寫颖系。
? parameterMappings:它是一個(gè)List<ParameterMapping>嗅剖,ParameterMapping的對(duì)象描述的是參數(shù)。包括:參數(shù)的屬性嘁扼、名稱信粮、表達(dá)式、javaType趁啸、jdbcType强缘、typeHandler等重要信息。通過它可以實(shí)現(xiàn)參數(shù)和SQL的結(jié)合不傅,以便PreparedStatement能夠通過它找到parameterObject對(duì)象的屬性并設(shè)置參數(shù)欺旧,使程序準(zhǔn)確的執(zhí)行。