MybatisPlus源码分析——从MybatisPlusAutoConfiguration说起

1,779 阅读2分钟

0.前言

接上文MybatisPlus Mapper层接口实现

1.MybatisPlusAutoConfiguration

为了深入理解MP中MybatisConfiguration相关属性及SqlSessionTemplate的创建,自MybatisPlusAutoConfiguration开始。在自动配置类中,存在方法sqlSessionFactory,该方法的返回值是SqlSessionFactory(可以理解为工厂bean的工厂bean,用来“生产”工厂) 分析源码可知此方法通过new MybatisSqlSessionFactoryBean来建立工厂的工厂,并通过getObject()方法返回工厂(类型为DefaultSqlSessionFactory)。此外,方法还会执行MyBatis本身组件、MyBatis-plus主键生成器、SQL 注入器等组件的注入操作,详见源码。

    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
        ...
        return factory.getObject();
    }

2.MybatisSqlSessionFactoryBean

通过getObject()方法进入MybatisSqlSessionFactoryBean,发现方法buildSqlSessionFactory()最终实现DefaultSqlSessionFactory的返回。该方法中,有一个重要对象targetConfiguration(类型是:MybatisConfiguration) 该对象的作用是存储MapperXML文件的解析信息,并用于生成SqlSessionFactory。

    protected SqlSessionFactory buildSqlSessionFactory() throws Exception {

        final MybatisConfiguration targetConfiguration;

        // TODO 使用 MybatisXmlConfigBuilder 而不是 XMLConfigBuilder
        MybatisXMLConfigBuilder xmlConfigBuilder = null;
        ...
        if (this.mapperLocations != null) {
            if (this.mapperLocations.length == 0) {
                LOGGER.warn(() -> "Property 'mapperLocations' was specified but matching resources are not found.");
            } else {
                for (Resource mapperLocation : this.mapperLocations) {
                    if (mapperLocation == null) {
                        continue;
                    }
                    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();
                    }
                    LOGGER.debug(() -> "Parsed mapper file: '" + mapperLocation + "'");
                }
            }
        } else {
            LOGGER.debug(() -> "Property 'mapperLocations' was not specified.");
        }
        final SqlSessionFactory sqlSessionFactory = new MybatisSqlSessionFactoryBuilder().build(targetConfiguration);
        ...
        return sqlSessionFactory;
        

XML文件的解析过程相当繁琐,在第三章进行介绍,本章仅对xml解析前后的targetConfiguration属性进行对比,能够发现,解析后mapper接口的xml信息存储在mybatisMpperRegistry属性中。

image.png

image.png

此外,从mybatisMpperRegistry开始,config->mappedStatements->key and value key存放的是xml中namespace+sql语句的id,value存放的是MappedStatement对象,其中属性SqlSource即对应id下的sql语句。

总而言之,在MybatisPlusAutoConfiguration进行工厂bean生产时,已经将mapperxml文件进行解析并存储在mybatisMapperRegistry中,并通过targetConfiguration传入到工厂bean ,在之后进行mapper注入,并调用接口方法时,工厂bean生产 SqlSessionTemplate对象,从而进行数据库查询。

image.png

3.Mapper接口的XML文件解析过程

未完待续...