mybatis 配置解析

本文参考如下:

  1. 配置文档 http://www.mybatis.org/mybatis-3/zh/configuration.html
  2. 代码 XMLConfigBuilder

处理流程

构造 XMLConfigBuilder 对象 parse
	创建 Configuration 对象 config
	创建 XPathParser 对象 parser
调用 XMLConfigBuilder 的 parse 方法
	调用 parser 的 evalNode 方法
		依次读取 properties,settings,typeAliases, plugins, objectFactory

配置

properties

读取顺序(后面覆盖前面):

  • 在 properties 元素内的指定的属性首先被读取。
  • 然后根据 properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性指定的路径读取属性文件。
  • 方法参数传递的属性。

该属性下设置的 key-value 可以用于其他地方。

settings

settings 下的属性必须是在 Configuration 下定义的属性,否则抛出异常。

问题:vfsImpl : 有什么用?

默认值配置

<settings>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <setting name="autoMappingUnknownColumnBehavior" value="NONE"/>
  <setting name="aggressiveLazyLoading" value="false"/>
  <setting name="cacheEnabled" value="true"/>
  <setting name="callSettersOnNulls" value="false"/>
  <setting name="configurationFactory" value=""/>    
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value=""/>
  <setting name="defaultFetchSize" value=""/>
  <setting name="defaultScriptingLanguage" value=""/>
  <setting name="defaultEnumTypeHandler" value=""/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadingEnabled" value="false"/>
  <setting name="localCacheScope" value="SESSION"/>
  <setting name="logPrefix" value=""/>  //没有默认值
  <setting name="logImpl" value=""/>  //没有默认值
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="proxyFactory" value=""/>    
  <setting name="returnInstanceForEmptyRow" value="false"/>
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="safeResultHandlerEnabled" value="true"/>
  <setting name="useColumnLabel" value="true"/>
  <setting name="useGeneratedKeys" value="false"/>
  <setting name="useActualParamName" value="true"/>
</settings>

typeAliases

功能

  1. 增加类名和类的映射关系
  2. 示例 1 加入 Configuration 的 typeAliasRegistry;示例 2 加入 BaseBuilder 的 typeAliasRegistry

除了默认关系, 还可以在 typaAliases 配置下注册,如示例 1 和示例 2

typeAliases 支持示例1 和 示例 2 两种配置类型别名的方式,但是只能支持其中一种。如果示例1 的配置存在,示例 2 的配置会被忽略。否则示例 2 的配置生效。

示例 1

<typeAliases>
  <package name="domain.blog"/>
</typeAliases>

包 domain.blog 下的类,如果有 Alias 注解,否则会用类的 SampleName 的形式为类型

@Alias("author")
public class Author {
    ...
}

示例 2

<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Comment" type="domain.blog.Comment"/>
  <typeAlias alias="Post" type="domain.blog.Post"/>
  <typeAlias alias="Section" type="domain.blog.Section"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

plugins

功能

  1. 实例化 interceptor 对应的类 class
  2. 将 plugin 中的所有 property 设置为 class 的属性
  3. 将 class 作为拦截器加入 Configuration

示例 1

<plugins>
  <plugin interceptor="org.mybatis.example.ExamplePlugin">
    <property name="someProperty" value="100"/>
  </plugin>
</plugins>

创建 org.mybatis.example.ExamplePlugin 对象,并设置下面 property 中的属性

objectFactory

功能

  1. 实例化 type 对应的类 class
  2. 将 objectFactory 中的所有 property 设置为 class 的属性
  3. 将 class 作为 Configuration 的 objectFactory

示例 1

<objectFactory type="org.mybatis.example.ExampleObjectFactory">
  <property name="someProperty" value="100"/>
</objectFactory>

objectWrapperFactory

功能

  1. 实例化 type 对应的类 class
  2. 将 class 作为 Configuration 的 objectWrapperFactory
<objectWrapperFactory type="org.mybatis.example.ExampleObjectFactory">
</objectWrapperFactory>

reflectorFactory

功能

  1. 实例化 type 对应的类 class
  2. 将 class 作为 Configuration 的 reflectorFactory
<reflectorFactory type="org.mybatis.example.ExampleObjectFactory">
</reflectorFactory>

environments

功能

  1. 解析 default 对应的 environment
  2. 设置 Configuration 的 environment

示例

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC"> <!-- MANAGED -->
      <property name="..." value="..."/>
    </transactionManager>
    <dataSource type="POOLED">  <!-- UNPOOLED|POOLED|JNDI -->
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
</environments>
  1. default 必须与某个 environment 的 id 匹配
  2. 设置 JDBC 对应的对象属性为 transactionManager 下的 property
  3. 设置 POOLED 对应的对象属性为 dataSource 下的 property

支持 UNPOOLED|POOLED|JNDI 三种类型:

这个数据源的实现只是每次被请求时打开和关闭连接。虽然有点慢,但对于在数据库连接可用性方面没有太高要求的简单应用程序来说,是一个很好的选择。 不同的数据库在性能方面的表现也是不一样的,对于某些数据库来说,使用连接池并不重要,这个配置就很适合这种情形。UNPOOLED 类型的数据源仅仅需要配置以下 5 种属性:

  • driver – 这是 JDBC 驱动的 Java 类的完全限定名(并不是 JDBC 驱动中可能包含的数据源类)。
  • url – 这是数据库的 JDBC URL 地址。
  • username – 登录数据库的用户名。
  • password – 登录数据库的密码。
  • defaultTransactionIsolationLevel – 默认的连接事务隔离级别。

作为可选项,你也可以传递属性给数据库驱动。要这样做,属性的前缀为“driver.”,例如:

  • driver.encoding=UTF8

这将通过 DriverManager.getConnection(url,driverProperties) 方法传递值为 UTF8encoding 属性给数据库驱动。

POOLED

这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这是一种使得并发 Web 应用快速响应请求的流行处理方式。

除了上述提到 UNPOOLED 下的属性外,还有更多属性用来配置 POOLED 的数据源:

  • poolMaximumActiveConnections – 在任意时间可以存在的活动(也就是正在使用)连接数量,默认值:10
  • poolMaximumIdleConnections – 任意时间可能存在的空闲连接数。
  • poolMaximumCheckoutTime – 在被强制返回之前,池中连接被检出(checked out)时间,默认值:20000 毫秒(即 20 秒)
  • poolTimeToWait – 这是一个底层设置,如果获取连接花费了相当长的时间,连接池会打印状态日志并重新尝试获取一个连接(避免在误配置的情况下一直安静的失败),默认值:20000 毫秒(即 20 秒)。
  • poolMaximumLocalBadConnectionTolerance – 这是一个关于坏连接容忍度的底层设置, 作用于每一个尝试从缓存池获取连接的线程. 如果这个线程获取到的是一个坏的连接,那么这个数据源允许这个线程尝试重新获取一个新的连接,但是这个重新尝试的次数不应该超过 poolMaximumIdleConnectionspoolMaximumLocalBadConnectionTolerance 之和。 默认值:3 (新增于 3.4.5)
  • poolPingQuery – 发送到数据库的侦测查询,用来检验连接是否正常工作并准备接受请求。默认是“NO PING QUERY SET”,这会导致多数数据库驱动失败时带有一个恰当的错误消息。
  • poolPingEnabled – 是否启用侦测查询。若开启,需要设置 poolPingQuery 属性为一个可执行的 SQL 语句(最好是一个速度非常快的 SQL 语句),默认值:false。
  • poolPingConnectionsNotUsedFor – 配置 poolPingQuery 的频率。可以被设置为和数据库连接超时时间一样,来避免不必要的侦测,默认值:0(即所有连接每一时刻都被侦测 — 当然仅当 poolPingEnabled 为 true 时适用)。

databaseIdProvider

功能

  1. 解析 type 创建 databaseIdProvider
  2. 从 environment 获取 DataSource,设置 Configuration 的 databaseId

示例

<databaseIdProvider type="DB_VENDOR">
  <property name="SQL Server" value="sqlserver"/>
  <property name="DB2" value="db2"/>        
  <property name="Oracle" value="oracle" />
</databaseIdProvider>

typeHandler

  1. 如果是 package,会将 package 下的类注册,否则将 jdbcType,javaType,handler 注册到Configuration 的 typeHandlerRegistry

示例 1

<typeHandlers>
  <package name="org.mybatis.example"/>
</typeHandlers>

示例 2

<typeHandlers>
  <typeHandler handler="org.mybatis.example.ExampleTypeHandler" jdbcType="", javaType=""/>
</typeHandlers>

注: MyBatis 不会窥探数据库元信息来决定使用哪种类型,所以你必须在参数和结果映射中指明那是 VARCHAR 类型的字段, 以使其能够绑定到正确的类型处理器上。 这是因为:MyBatis 直到语句被执行才清楚数据类型。

通过类型处理器的泛型,MyBatis 可以得知该类型处理器处理的 Java 类型,不过这种行为可以通过两种方法改变:

  • 在类型处理器的配置元素(typeHandler element)上增加一个 javaType 属性(比如:javaType="String");
  • 在类型处理器的类上(TypeHandler class)增加一个 @MappedTypes 注解来指定与其关联的 Java 类型列表。 如果在 javaType 属性中也同时指定,则注解方式将被忽略。

可以通过两种方式来指定被关联的 JDBC 类型:

  • 在类型处理器的配置元素上增加一个 jdbcType 属性(比如:jdbcType="VARCHAR");
  • 在类型处理器的类上(TypeHandler class)增加一个 @MappedJdbcTypes 注解来指定与其关联的 JDBC 类型列表。 如果在 jdbcType 属性中也同时指定,则注解方式将被忽略。

当决定在ResultMap中使用某一TypeHandler时,此时java类型是已知的(从结果类型中获得),但是JDBC类型是未知的。 因此Mybatis使用javaType=[TheJavaType], jdbcType=null的组合来选择一个TypeHandler。 这意味着使用@MappedJdbcTypes注解可以限制TypeHandler的范围,同时除非显式的设置,否则TypeHandler在ResultMap中将是无效的。 如果希望在ResultMap中使用TypeHandler,那么设置@MappedJdbcTypes注解的includeNullJdbcType=true即可。 然而从Mybatis 3.4.0开始,如果只有一个注册的TypeHandler来处理Java类型,那么它将是ResultMap使用Java类型时的默认值(即使没有includeNullJdbcType=true)。

mapper

功能

  1. 如果是 package,扫描 name 对应的包,否则构造 XMLMapperBuilder 对象,调用 parser 方法

示例

<!-- 使用相对于类路径的资源引用 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>
  1. resourde, url, class 同时只能有一个生效,优先级 resource > url > class

附录

mybatis 默认数据库类型与 Java 映射关系

    string: String

    byte: Byte
    long: Long
    short: Short
    int: Integer
    integer: Integer
    double: Double
    float: Float
    boolean: Boolean

    byte[]: Byte[]
    long[]: Long[]
    short[]: Short[]
    int[]: Integer[]
    integer[]: Integer[]
    double[]: Double[]
    float[]: Float[]
    boolean[]: Boolean[]

    _byte: byte
    _long: long
    _short: short
    _int: int
    _integer: int
    _double: double
    _float: float
    _boolean: boolean

    _byte[]: byte[]
    _long[]: long[]
    _short[]: short[]
    _int[]: int[]
    _integer[]: int[]
    _double[]: double[]
    _float[]: float[]
    _boolean[]: boolean[]

    date: Date
    decimal: BigDecimal
    bigdecimal: BigDecimal
    biginteger: BigInteger
    object: Object

    date[]: Date[]
    decimal[]: BigDecimal[]
    bigdecimal[]: BigDecimal[]
    biginteger[]: BigInteger[]
    object[]: Object[]

    map: Map
    hashmap: HashMap
    list: List
    arraylist: ArrayList
    collection: Collection
    iterator: Iterator

    ResultSet: ResultSet
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值