使用MyBatis是,需要使用XML配置MyBatis需要的参数。应用启动的时候,xml配置会被解析加载到内存,后续SQL执行时就可以直接使用。
MyBatis有个类是Configuration,顾名思义,这个类和配置相关,MyBatis解析XML配置都会存储到这个类的对象里面,后续SQL执行时,直接从这个类的对象获取配置值。
相关MyBatis配置值,按照用途,主要划分了以下几种:
- properties:自定义配置变量
- settings:MyBatis配置,可以改变MyBatis行为
- typeAliases:类型别名
- typeHandlers:类型转换处理器
- objectFactory:对象工厂
- environments:数据库环境信息,包含了事务配置和数据源配置
- databaseIdProvider:数据库产品提供者
- mappers:映射器
解析这些配置之后,保存在Configuration类的对象里面,这时Configuration类的对象的结构就像下图所示。
variables
variables的结构就是Properties,把XML文件里的配置变量值以key-value形式存储起来。
这里有个规则需要注意一下,如果一个属性在不只一个地方进行了配置,那么,MyBatis 将按照下面的顺序来加载:
- 首先读取在 properties 元素体内指定的属性。
- 然后根据 properties 元素中的 resource 属性读取类路径下属性文件,或根据 url 属性指定的路径读取属性文件,并覆盖之前读取过的同名属性。
- 最后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性。
settings
settings涉及很多影响MyBatis行为的变量,如果XML文件里配置了值,会拿配置的值覆盖默认的值。
settings配置的值设置的时候涉及一个反射相关的类MetaClass,MyBatis会使用这个类判断XML配置的setting是否有对应的setter方法。
typeAliasRegistry
底层使用一个HashMap保存类型别名的配置。
objectFactory
默认是DefaultObjectFactory,是个对象工厂,生成SQL查询、操作结果时会用到。
environment
里面包含了三个重要的变量,id、transactionFactory、dataSource。
id表示这个environment使用的是哪个environment配置,transactionFactory是个事务工厂,生成事务对象,dataSource保存了数据源配置。
databaseId
保存了数据库厂商信息。
typeHandlerRegistry
typeHandlerRegistry包含了几个变量:
- JDBC_TYPE_HANDLER_MAP:保存了jdbcType对应的typeHandler
- TYPE_HANDLER_MAP:保存了javaType对应的typeHandler,value是个Map,保存了jdbcType、typeHandler的key-value数据
- UNKNOW_TYPE_HANDLER:兜底用到的typeHandler,使用javaType、jdbcType获取不到对应的typeHandler会使用这个typeHandler
- ALL_TYPE_HANDLERS_MAP:保存所有的typeHandler,保存了javaType、typeHandler的key-value数据
mapperRegistry
mapper下涉及到六个节点:
- cache-ref:和别的命名空间共用缓存,指向共用的命名空间,二级缓存
- cache:缓存配置,二级缓存
- parameterMap:已经被废弃掉了
- resultMap:结果集的映射关系
- sql:SQL语句片段
- select|insert|update|delete:SQL语句
说到mapperRegistry,需要先说到对象configuration里的这几个变量:
- cacheRefMap:保存了cache-ref节点的解析结果,保存了引用namespace、被引用namespace的key-value数据
- mappedStatements:保存了解析后的mapper数据
- caches:保存了cache节点的解析结果,保存了namespace、缓存的key-value数据
- resultMaps:保存了resultMap节点的解析结果,保存了resultMapId、resultMap的key-value数据
- parameterMaps:已经被废弃了
MyBatis解析mapper节点的时候,会根据配置文件信息构建cache对象、resultMap对象、parameterMap对象、cache-ref引用关系、mappedStatement对象,在这个过程中,MyBatis会把mapper节点解析成SqlSource,里面包含SQL语句解析后的节点的信息,顶层信息是MixedSqlNode。
再看一下mapperRegistry的结构,可以发现mapperRegistry保存了一个HashMap,保存了Class、MapperProxyFactory的key-value数据,这个HashMap保存了Mapper接口类和对应的代理工厂,调用执行mapper时,会使用到mapper的全限定名找到解析好的mappedStatements,生成真正的执行逻辑。