MP版本爲3.0.1java
①,入口類 com.baomidou.mybatisplus.core.injector.AbstractSqlInjector ,重點是這個方法spring
public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) { String className = mapperClass.toString(); Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration()); if (!mapperRegistryCache.contains(className)) { List<AbstractMethod> methodList = this.getMethodList(); Assert.notEmpty(methodList, "No effective injection method was found."); // 循環注入自定義方法,這裏開始注入sql methodList.forEach(m -> m.inject(builderAssistant, mapperClass)); mapperRegistryCache.add(className); /** * 初始化 SQL 解析 */ if (GlobalConfigUtils.getGlobalConfig(builderAssistant.getConfiguration()).isSqlParserCache()) { SqlParserHelper.initSqlParserInfoCache(mapperClass); } } }
②,由AbstractMethod 的injectMappedStatement 方法完成具體的注入,sql
咱們看到實際是有其實現類的一個個injectMappedStatement 來完成注入的apache
③,這裏我以DeleteById 爲例session
@Override public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) { //獲得待解析sql的模板 SqlMethod sqlMethod = SqlMethod.DELETE_BY_ID; //利用語言驅動和配置信息,table元數據,和剛纔獲得的sql方法模板獲得sqlSource SqlSource sqlSource = languageDriver.createSqlSource(configuration, String.format(sqlMethod.getSql(), tableInfo.getTableName(), tableInfo.getKeyColumn(), tableInfo.getKeyProperty()), modelClass); //最後添加到mybatis的configuration裏的mappedStatements中 return this.addDeleteMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource); }
④,DELETE_BY_ID的模板以下mybatis
由此咱們能夠猜出,在tableInfo 中必需要能得出表名和該表主鍵app
咱們能夠在該方法的第一行打一個斷點ide
看我紅框圈起來的部門,咱們能夠大體猜出,是spring容器在實例化組件時,在實例化組件後調用組件的初始化方法,而引發的一連串反應。ui
經過翻看源碼,我大體解釋一下this
1,AbstractAutowireCapableBeanFactory調用組件的afterPropertiesSet方法,這個組件的beanName爲userMapper,這是一個我定義的一個繼承自BaseMapper的一個接口
2,不知怎麼地,竟然跑去調用 DaoSupport的afterPropertiesSet方法(知道的朋友歡迎留言)
3,而後調用到了其子類的MapperFactoryBean 的checkDaoConfig方法
重點是一行,這個configuration是繼承自org.apache.ibatis.session.Configuration 的子類,是有mp自定義的一個類
configuration.addMapper(this.mapperInterface);
4,接下來調用com.baomidou.mybatisplus.core.MybatisMapperRegistry的addMapper方法
斷點停在了86行
5,咱們看這個parse方法
利用GlobalConfigUtils 獲得ISqlInjector,而後調用其inspectInject方法
6,咱們看看mp是如何獲得這個ISqlInjector的
public static ISqlInjector getSqlInjector(Configuration configuration) { // fix #140 GlobalConfig globalConfiguration = getGlobalConfig(configuration); //從配置裏拿,若是有,則用配置的 ISqlInjector sqlInjector = globalConfiguration.getSqlInjector(); if (sqlInjector == null) { //沒有配置,默認給一個DefaultSqlInjector sqlInjector = new DefaultSqlInjector(); globalConfiguration.setSqlInjector(sqlInjector); } return sqlInjector; }
7,而 DefaultSqlInjector 是繼承自 AbstractSqlInjector 類的
因爲DefaultSqlInjector沒有重寫AbstractSqlInjector的inspectInject方法,
因此DefaultSqlInjector在調用inspectInject方法時,實際上會用父類AbstractSqlInjector的inspectInject方法。