mybatis源码学习之——配置详解一

使用mybatis首先要了解的就是其配置文件及每项配置的使用方法和注意事项,在此参考官网的配置介绍,挑其中比较常用的几项配置进行学习。

首先我们要了解配置文件的层级结构:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <properties></properties> <!--属性-->
  <settings></settings> <!--设置:用于改变 MyBatis 的运行时行为-->
  <typeAliases></typeAliases>  <!--类型别名:用来减少类完全限定名的冗余-->
  <typeHandlers></typeHandlers>  <!--类型处理器:用于将获取的值以合适的方式转换成 Java 类型-->
  <objectFactory></objectFactory> <!--对象工厂:用来通过提供的默认构造方法或通过参数构造方法来实例化对象-->
  <plugins> <!--插件:通过拦截特定位置进行相应处理-->
    <plugin></plugin>
  </plugins>
  <environments> <!--环境配置:配置成适应多种环境,如开发、测试、生产等-->
      <environment>
          <transactionManager></transactionManager>
          <dataSource></dataSource>
      </environment>
  </environments>
  <databaseIdProvider></databaseIdProvider> <!--数据库厂商标识:根据不同的数据库厂商执行不同的语句 -->
  <mappers> <!--映射器:告诉 MyBatis 到哪里去找映射文件-->
       <mapper/>
  </mappers>
</configuration>

下面具体介绍一下几个常用的配置:

1、properties(配置)

这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。如:

<properties resource="com/mybatis/mine/config.properties">
  <property name="username" value="luxy"/>
  <property name="password" value="******"/>
</properties>

这样我们就可以在整个配置文件中使用${变量名} 进行设置,如:

<dataSource type="POOLED">
    <property name="driver" value="${driver}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>
</dataSource>

而driver和url在config.properties中有设置:

driver = com.mysql.jdbc.Driver
url = jdbc:mysql://www.xxx.com:3306/luxydb

值得注意的是,当一个配置参数在多个地方被配置的话,优先级顺序如下:

  • 在 properties 元素体内指定的属性首先被读取。
  • 然后根据 properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性指定的路径读取属性文件,并覆盖已读取的同名属性。
  • 最后读取作为方法参数传递的属性,并覆盖已读取的同名属性。

2、settings(设置)

主要用来设置运行时的一些行为参数,常用的参数有以下几种:

<settings>  
         <!-- 这个配置使全局的映射器启用或禁用缓存 -->  
         <setting name="cacheEnabled" value="false" />
       
         <!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载 -->  
         <setting name="lazyLoadingEnabled" value="false" />
         
	<!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载 -->  
         <setting name="aggressiveLazyLoading" value="true" />
           
	<!-- 允许或不允许多种结果集从一个单独的语句中返回(需要适合的驱动) -->  
         <setting name="multipleResultSetsEnabled" value="true" />
           
	<!-- 使用列标签代替列名。不同的驱动在这方便表现不同。参考驱动文档或充分测试两种方法来决定所使用的驱动 -->  
         <setting name="useColumnLabel" value="true" />
           
	<!-- 允许JDBC支持生成的键。需要适合的驱动。如果设置为true则这个设置强制生成的键被使用,尽管一些驱动拒绝兼容但仍然有效(比如Derby) -->  
         <setting name="useGeneratedKeys" value="true" />
           
	<!-- 指定MyBatis如何自动映射列到字段/属性。PARTIAL只会自动映射简单,没有嵌套的结果。FULL会自动映射任意复杂的结果(嵌套的或其他情况) -->  
         <setting name="autoMappingBehavior" value="PARTIAL" />
           
	<!--当检测出未知列(或未知属性)时,如何处理,默认情况下没有任何提示,这在测试的时候很不方便,不容易找到错误。
		NONE : 不做任何处理 (默认值)
		WARNING : 警告日志形式的详细信息
		FAILING : 映射失败,抛出异常和详细信息
	-->
	<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
		
	<!-- 配置默认的执行器。SIMPLE执行器没有什么特别之处。REUSE执行器重用预处理语句。BATCH执行器重用语句和批量更新 -->  
         <setting name="defaultExecutorType" value="SIMPLE" />
          
	<!-- 设置超时时间,它决定驱动等待一个数据库响应的时间 -->  
         <setting name="defaultStatementTimeout" value="250000" />  
	<!--设置查询返回值数量,可以被查询数值覆盖  -->
	<setting name="defaultFetchSize" value="100"/>
		
	<!-- 允许在嵌套语句中使用分页-->
	<setting name="safeRowBoundsEnabled" value="false"/>
		
	<!--是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。-->
	<setting name="mapUnderscoreToCamelCase" value="true"/>
		
	<!--MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。-->
	<setting name="localCacheScope" value="SESSION"/>
		
	<!-- 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR、OTHER。-->
	<setting name="jdbcTypeForNull" value="OTHER"/>
		
	<!-- 指定哪个对象的方法触发一次延迟加载。-->
	<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

3、typeAliases(别名)

类型别名是为 Java 类型设置一个短的名字。 它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。如:

<typeAliases>
  <typeAlias alias="User" type="com.mybatis.mine.User"/>
</typeAliases>

4、plugins(插件)

MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)

以下是我实现的一个简单的插件,输出查询sql执行的耗时时间:

package com.mybatis.mine;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.util.Properties;

@Intercepts({@Signature(
  type= Executor.class,method = "query",args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class MyInterceptor implements Interceptor {

  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    Long startTime = System.currentTimeMillis();
    System.out.println("开始时间:" + startTime);
    Object object = invocation.proceed();
    Long endTime = System.currentTimeMillis();
    System.out.println("结束时间:" + endTime + ";耗时:" + (endTime - startTime));
    return object;
  }

  @Override
  public Object plugin(Object target) {
    return Plugin.wrap(target, this);
  }

  @Override
  public void setProperties(Properties properties) {
    System.out.println("慢sql耗时阀值:" + properties.getProperty("time_too_long"));
  }
}

在配置文件中的配置如下:

<plugins>
    <plugin interceptor="com.mybatis.mine.MyInterceptor">
      <property name="time_too_long" value="50000"/>
    </plugin>
</plugins>

执行测试用例的结果:

慢sql耗时阀值:50000
开始时间:1557124288707
结束时间:1557124289738;耗时:1031
User{userCode='10', userName='李四03', createTime=Tue Apr 16 11:46:04 CST 2019, userType='01', mobile='18701234589'}

有上可以看出,我们可以通过<plugin>中的<property>设置插件中需要使用到的参数,并通过setProperties()方法获取设置到的参数。这样我们就可以根据自身的需要来对mybatis进行扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值