栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mybatis(7)- 源码解析(1)读取配置 Configuration

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mybatis(7)- 源码解析(1)读取配置 Configuration

Mybatis(3)- 源码解析(1)读取配置 Configuration

从MyBatis入门使用文章中可知,MyBatis在使用前有一些前置的配置,并且每个Mapper接口需要对应一个 *Mapper.xml 的配置文件,这篇文章将解析 Mybatis 读取配置文件的过程。

public class Main {
    public static void main(String[] args) {
        String resource = "mybatis-config.xml";
        SqlSession session = null;
        try {
            InputStream inputStream = Resources.getResourceAsStream(resource);
            // 读取配置的过程在 build 方法过程中
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            System.out.println(sqlSessionFactory);
            session = sqlSessionFactory.openSession();
            ActorMapper actorMapper = session.getMapper(ActorMapper.class);
            Actor actor = actorMapper.selectOneActor(1);
            System.out.println(actor);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }

    }
}
解析 mybatis-config.xml

mybatis-config.xml 配置文件:





    

    
        
            
            
                
                
                
                
            
        
    

    
        
    


Configuration

public class Configuration {
    protected Environment environment;
    protected boolean safeRowBoundsEnabled;
    protected boolean safeResultHandlerEnabled;
    protected boolean mapUnderscoreToCamelCase;
    protected boolean aggressiveLazyLoading;
    protected boolean multipleResultSetsEnabled;
    protected boolean useGeneratedKeys;
    protected boolean useColumnLabel;
    protected boolean cacheEnabled;
    protected boolean callSettersOnNulls;
    protected boolean useActualParamName;
    protected boolean returnInstanceForEmptyRow;
    protected boolean shrinkWhitespacesInSql;
    protected String logPrefix;
    protected Class logImpl;
    protected Class vfsImpl;
    protected Class defaultSqlProviderType;
    // 一级缓存配置,默认值为 SESSION,表示在同一个 session 连接中执行同一个SQL会使用上一次的查询结果缓存,
    // 当配置成 STATEMENT 时不使用一级缓存
    protected LocalCacheScope localCacheScope;
    protected JdbcType jdbcTypeForNull;
    protected Set lazyLoadTriggerMethods;
    protected Integer defaultStatementTimeout;
    protected Integer defaultFetchSize;
    protected ResultSetType defaultResultSetType;
    protected ExecutorType defaultExecutorType;
    protected AutoMappingBehavior autoMappingBehavior;
    protected AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior;
    protected Properties variables;
    protected ReflectorFactory reflectorFactory;
    protected ObjectFactory objectFactory;
    protected ObjectWrapperFactory objectWrapperFactory;
    protected boolean lazyLoadingEnabled;
    protected ProxyFactory proxyFactory;
    protected String databaseId;
    protected Class configurationFactory;
    protected final MapperRegistry mapperRegistry;
    protected final InterceptorChain interceptorChain;
    protected final TypeHandlerRegistry typeHandlerRegistry;
    protected final TypeAliasRegistry typeAliasRegistry;
    protected final LanguageDriverRegistry languageRegistry;
    protected final Map mappedStatements;
    protected final Map caches;
    protected final Map resultMaps;
    protected final Map parameterMaps;
    protected final Map keyGenerators;
    protected final Set loadedResources;
    protected final Map sqlFragments;
    protected final Collection incompleteStatements;
    protected final Collection incompleteCacheRefs;
    protected final Collection incompleteResultMaps;
    protected final Collection incompleteMethods;
    protected final Map cacheRefMap;
    
    // 构造方法给 Configuration 赋的是默认值
    public Configuration() {
        this.safeResultHandlerEnabled = true;
        this.multipleResultSetsEnabled = true;
        this.useColumnLabel = true;
        this.cacheEnabled = true;
        this.useActualParamName = true;
        this.localCacheScope = LocalCacheScope.SESSION;
        this.jdbcTypeForNull = JdbcType.OTHER;
        this.lazyLoadTriggerMethods = new HashSet(Arrays.asList("equals", "clone", "hashCode", "toString"));
        this.defaultExecutorType = ExecutorType.SIMPLE;
        this.autoMappingBehavior = AutoMappingBehavior.PARTIAL;
        this.autoMappingUnknownColumnBehavior = AutoMappingUnknownColumnBehavior.NONE;
        this.variables = new Properties();
        this.reflectorFactory = new DefaultReflectorFactory();
        this.objectFactory = new DefaultObjectFactory();
        this.objectWrapperFactory = new DefaultObjectWrapperFactory();
        this.lazyLoadingEnabled = false;
        this.proxyFactory = new JavassistProxyFactory();
        this.mapperRegistry = new MapperRegistry(this);
        this.interceptorChain = new InterceptorChain();
        this.typeHandlerRegistry = new TypeHandlerRegistry(this);
        this.typeAliasRegistry = new TypeAliasRegistry();
        this.languageRegistry = new LanguageDriverRegistry();
        this.mappedStatements = (new Configuration.StrictMap("Mapped Statements collection")).conflictMessageProducer((savedValue, targetValue) -> {
            return ". please check " + savedValue.getResource() + " and " + targetValue.getResource();
        });
        this.caches = new Configuration.StrictMap("Caches collection");
        this.resultMaps = new Configuration.StrictMap("Result Maps collection");
        this.parameterMaps = new Configuration.StrictMap("Parameter Maps collection");
        this.keyGenerators = new Configuration.StrictMap("Key Generators collection");
        this.loadedResources = new HashSet();
        this.sqlFragments = new Configuration.StrictMap("XML fragments parsed from previous mappers");
        this.incompleteStatements = new LinkedList();
        this.incompleteCacheRefs = new LinkedList();
        this.incompleteResultMaps = new LinkedList();
        this.incompleteMethods = new LinkedList();
        this.cacheRefMap = new HashMap();
        this.typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
        this.typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
        this.typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
        this.typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
        this.typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);
        this.typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
        this.typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
        this.typeAliasRegistry.registerAlias("LRU", LruCache.class);
        this.typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
        this.typeAliasRegistry.registerAlias("WEAK", WeakCache.class);
        this.typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class);
        this.typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);
        this.typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);
        this.typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
        this.typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);
        this.typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
        this.typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
        this.typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
        this.typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
        this.typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);
        this.typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
        this.typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);
        this.languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);
        this.languageRegistry.register(RawLanguageDriver.class);
    }
}

SqlSessionFactoryBuilder build 方法

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    SqlSessionFactory var5;
    try {
        // 构建解析 XML 的对象 XMLConfigBuilder
        XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
        var5 = this.build(parser.parse());
    } catch (Exception var14) {
        throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
    } finally {
        ErrorContext.instance().reset();

        try {
            inputStream.close();
        } catch (IOException var13) {
        }

    }

    return var5;
}

XMLConfigBuilder

public class XMLConfigBuilder extends BaseBuilder {
    private boolean parsed;
    private final XPathParser parser;
    private String environment;
    private final ReflectorFactory localReflectorFactory;
    
    private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
        // 给 Configuration 赋初始值 
        super(new Configuration());
        this.localReflectorFactory = new DefaultReflectorFactory();
        ErrorContext.instance().resource("SQL Mapper Configuration");
        this.configuration.setVariables(props);
        this.parsed = false;
        this.environment = environment;
        this.parser = parser;
    }
}

XMLConfigBuilder 父类 BaseBuilder

public abstract class BaseBuilder {
    // 解析xml后的配置都存放在 Configuration 中
    protected final Configuration configuration;
    protected final TypeAliasRegistry typeAliasRegistry;
    protected final TypeHandlerRegistry typeHandlerRegistry;
    
    public BaseBuilder(Configuration configuration) {
        this.configuration = configuration;
        this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
        this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
    }
}

重点看下 XMLConfigBuilder parse 方法,此方法为解析 mybatis-config.xml 文件的入口

XMLConfigBuilder parse 方法,此方法返回 Configuration 对象作为 build 方法入参

public Configuration parse() {
    if (this.parsed) {
        throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    } else {
        this.parsed = true;
        this.parseConfiguration(this.parser.evalNode("/configuration"));
        return this.configuration;
    }
}

XMLConfigBuilder parseConfiguration 方法

对照 mybatis-config.xml 文件,读取对应的配置项

private void parseConfiguration(XNode root) {
    try {
        this.propertiesElement(root.evalNode("properties"));
        Properties settings = this.settingsAsProperties(root.evalNode("settings"));
        this.loadCustomVfs(settings);
        this.loadCustomLogImpl(settings);
        this.typeAliasesElement(root.evalNode("typeAliases"));
        this.pluginElement(root.evalNode("plugins"));
        this.objectFactoryElement(root.evalNode("objectFactory"));
        this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
        this.reflectorFactoryElement(root.evalNode("reflectorFactory"));
        this.settingsElement(settings);
        this.environmentsElement(root.evalNode("environments"));
        this.databaseIdProviderElement(root.evalNode("databaseIdProvider"));
        this.typeHandlerElement(root.evalNode("typeHandlers"));
        // 解析  配置
        this.mapperElement(root.evalNode("mappers"));
    } catch (Exception var3) {
        throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3);
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/858185.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号