mybatis-plus解析注解,自动生成sqlNode

        本文介绍,mybatis-plus在项目启动的时候,解析实体类的注解,比如:@Table等,生成sqlNode,然后在真正访问的时候,再拼接成sql语句。

访问流程:

入口:
1. com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean#buildSqlSessionFactory
//  构建SqlSession的时候根据接口解析自动生成的sqlNode。
protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
// 省略大部分代码
	try {
			XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
				targetConfiguration, mapperLocation.toString(), targetConfiguration.getSqlFragments());
			xmlMapperBuilder.parse();
		} catch (Exception e) {
			throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
		} finally {
			ErrorContext.instance().reset();
		}
	}

//2. 解析xml配置,也可以解析注解生成xml配置
org.apache.ibatis.builder.xml.XMLMapperBuilder#parse
public void parse() {
    if (!configuration.isResourceLoaded(resource)) {
      configurationElement(parser.evalNode("/mapper"));
      configuration.addLoadedResource(resource);
	  //这调用构建sqlsource
      bindMapperForNamespace();
    }

    parsePendingResultMaps();
    parsePendingCacheRefs();
    parsePendingStatements();
  }

//3. 构建xml
org.apache.ibatis.builder.xml.XMLMapperBuilder#bindMapperForNamespace
private void bindMapperForNamespace() {
    String namespace = builderAssistant.getCurrentNamespace();
    if (namespace != null) {
      Class<?> boundType = null;
      try {
        boundType = Resources.classForName(namespace);
      } catch (ClassNotFoundException e) {
        // ignore, bound type is not required
      }
      if (boundType != null && !configuration.hasMapper(boundType)) {
        // Spring may not know the real resource name so we set a flag
        // to prevent loading again this resource from the mapper interface
        // look at MapperAnnotationBuilder#loadXmlResource
        configuration.addLoadedResource("namespace:" + namespace);
		//这里调用
        configuration.addMapper(boundType);
      }
    }
  }

//4. 解析mapper,并注册
com.baomidou.mybatisplus.core.MybatisConfiguration#addMapper
@Override
    public <T> void addMapper(Class<T> type) {
        mybatisMapperRegistry.addMapper(type);
    }

//  5. 解析
com.baomidou.mybatisplus.core.MybatisMapperRegistry#addMapper
@Override
    public <T> void addMapper(Class<T> type) {
        if (type.isInterface()) {
            if (hasMapper(type)) {
                // TODO 如果之前注入 直接返回
                return;
                // TODO 这里就不抛异常了
//                throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
            }
            boolean loadCompleted = false;
            try {
                // TODO 这里也换成 MybatisMapperProxyFactory 而不是 MapperProxyFactory
                knownMappers.put(type, new MybatisMapperProxyFactory<>(type));
                // It's important that the type is added before the parser is run
                // otherwise the binding may automatically be attempted by the
                // mapper parser. If the type is already known, it won't try.
                // TODO 这里也换成 MybatisMapperAnnotationBuilder 而不是 MapperAnnotationBuilder
				
				//最重要的就是下面这2行
                MybatisMapperAnnotationBuilder parser = new MybatisMapperAnnotationBuilder(config, type);
                parser.parse();
                loadCompleted = true;
            } finally {
                if (!loadCompleted) {
                    knownMappers.remove(type);
                }
            }
        }
    }


//6. 解析注解的类
com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder#parse
@Override
    public void parse() {
	// 删除部分代码...
       
		// TODO 注入 CURD 动态 SQL , 放在在最后, because 可能会有人会用注解重写sql
		try {
			// https://github.com/baomidou/mybatis-plus/issues/3038
			if (GlobalConfigUtils.isSupperMapperChildren(configuration, type)) {
				parserInjector();
			}
		} catch (IncompleteElementException e) {
			configuration.addIncompleteMethod(new InjectorResolver(this));
		}
        
    }

//7. 解析注入
com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder#parserInjector
    void parserInjector() {
        GlobalConfigUtils.getSqlInjector(configuration).inspectInject(assistant, type);
    }

//8. 解析自定义方法
com.baomidou.mybatisplus.core.injector.AbstractSqlInjector#inspectInject
methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));


//9.注入
com.baomidou.mybatisplus.core.injector.AbstractMethod#inject
public void inject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        this.configuration = builderAssistant.getConfiguration();
        this.builderAssistant = builderAssistant;
        this.languageDriver = configuration.getDefaultScriptingLanguageInstance();
        /* 注入自定义方法 */
        injectMappedStatement(mapperClass, modelClass, tableInfo);
    }

大家,可以在上面这几个位置,打断点,然后再看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用MyBatis-Plus生成XML配置的代码,你需要进行以下配置: 1. 在application.properties文件中,配置MyBatis-Plus的相关属性,如开启SQL日志、映射下划线字段为驼峰格式等。\[1\] 2. 创建一个配置类(如MyBatisPlusConfig),使用@Configuration注解标记为配置类,并使用@MapperScan注解指定要扫描的mapper文件夹。在该配置类中,你可以注册乐观锁插件和逻辑删除组件。\[2\] 3. 创建另一个配置类(如MybatisConfig),同样使用@Configuration注解标记为配置类,并使用@EnableTransactionManagement注解开启事务管理。在该配置类中,你可以配置MyBatis-Plus的分页插件。\[3\] 通过以上配置,你就可以使用MyBatis-Plus生成XML配置的代码了。 #### 引用[.reference_title] - *1* *3* [spring boot 2 整合 mybatis-plus 3.5.1,mybatis-plus-generator 自动生成代码](https://blog.csdn.net/bish326/article/details/123661864)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [MyBatis-Plus——代码自动生成器](https://blog.csdn.net/Huang_ZX_259/article/details/122540801)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值