一、 mybatis初始化
类似于 Spring、 MyBatis 等灵活性和可扩展性都很高的开源框架都提供了很多配置项,开发人员需要在使用时提供相应的配置信息,实现相应的需求。
MyBatis 中的配置文件主要有两 个,分别是 mybatis-config.xml 配置文件和映射配置文件。 现在主流的配置方式除了使用 XML 配置文件,还会配合注解进行配置。在 MyBatis 初始 化的过程中,除了会读取 mybatis-config.xml 配置文件以及映射配置文件,还会加载配直文件指 定的类,处理类中的注解,创建一些配置对象,最终完成框架中各个模块的初始化。另外,也 可以使用 Java API 的方式对 MyBatis 进行配置,这种硬编码的配置方式主要用在配置量比较少 且配置信息不常变化的场景下。
1.1mybatis初始化
过程主要使用建造者模型
- XMLConfigBuilder:主要负责解释mybatis-config.xml
- XMLMapperBuilder:负责解析映射配置文件
- XMLStatementBuilder:负责解析映射配置文件中的SQL结点
1.2 映射器的关键类
- Configuration:Mybatis启动初始化的核心就是将所有xml配置文件信息加载到Configuration对象中,Configuration是单例的,生命周期是应用级的
- MapperRegistry:mapper接口动态代理工厂类的注册中心。在Mybatis中,通过mapperProxy实现InvocationHandler接口,MapperProxyFactory用于生成动态代理的实例对象
- ResultMap:用于解析mapper.xml文件中的resultMap节点,使用ResultMapping来封装id、result等子元素
- MappedStatement:用于存储mapper.xml文件中的select、insert、update和delete节点,同时还包含了这些节点很多重要属性
- SqlSource:mapper.xml文件中sql语句会被解析成SqlSource对象,经过解析SqlSource包含的语句最终仅仅包含?占位符,可以直接交给数据库执行。
1.3 configuration类图解
1.4 ResultMap图解
1.5 mappedStatment图解
二 、源码解析
2.1 Configuration的域对应mybatis-config.xml中相应的配置项
public class Configuration {
protected Environment environment;
/* 是否启用数据组A_column自动映射到Java类中的驼峰命名的属性**/
protected boolean mapUnderscoreToCamelCase;
/*当对象使用延迟加载时 属性的加载取决于能被引用到的那些延迟属性,否则,按需加载(需要的是时候才去加载)**/
protected boolean aggressiveLazyLoading;
/*是否允许单条sql 返回多个数据集 (取决于驱动的兼容性) default:true **/
protected boolean multipleResultSetsEnabled = true;
/*-允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。 default:false**/
protected boolean useGeneratedKeys;
/*配置全局性的cache开关,默认为true**/
protected boolean cacheEnabled = true;
/*指定 MyBatis 应如何自动映射列到字段或属性*/
protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL;
/*MyBatis每次创建结果对象的新实例时,它都会使用对象工厂(ObjectFactory)去构建POJO*/
protected ObjectFactory objectFactory = new DefaultObjectFactory();
protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();
/*延迟加载的全局开关*/
protected boolean lazyLoadingEnabled = false;
/*指定 Mybatis 创建具有延迟加载能力的对象所用到的代理工具*/
protected ProxyFactory proxyFactory = new JavassistProxyFactory(); // #224 Using internal Javassist instead of OGNL
/*插件集合*/
protected final InterceptorChain interceptorChain = new InterceptorChain();
/*TypeHandler注册中心*/
protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();
/*TypeAlias注册中心*/
protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();
protected final LanguageDriverRegistry languageRegistry = new LanguageDriverRegistry();
//-------------------------------------------------------------
/*mapper接口的动态代理注册中心*/
protected final MapperRegistry mapperRegistry = new MapperRegistry(this);
/*mapper文件中增删改查操作的注册中心*/
protected final Map<String, MappedStatement> mappedStatements = new StrictMap<>("Mapped Statements collection");
/*mapper文件中配置的所有resultMap对象 key为命名空间+ID*/
protected final Map<String, ResultMap> resultMaps = new StrictMap<>("Result Maps collection");
protected final Map<String, ParameterMap> parameterMaps = new StrictMap<>("Parameter Maps collection");
/*加载到的所有*mapper.xml文件*/
protected final Set<String> loadedResources = new HashSet<>();
2.2 BaseBuilder
MyBatis 初始化的主 要工作是加载井解析 mybatis-config.xml 配置文件、映射配置文件以及相关的注解信息。 MyBatis 的初始化入口是 SqlSessionFactoryBuilder. build()方法,其具体实现如下:
// 读取mybatis配置文件
inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//1. SqlSessionFactoryBuilder创建 SqlSessionFactory
/**
* 读取配置信息创建SqlSessionFactory,建造者模式,方法级别生命周期;
* SqlSessionFactory:创建Sqlsession,工厂单例模式,存在于程序的整个生命周期;
*/
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
////读取配置文件
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
//解析配置文件得到 Configuration 对象,创建 DefaultSqlSessionFactory 对象
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {