Mybatis 的XML配置文件包含了设置和影响 Mybatis 行为的属性。XML 配置文件的层次结构如下:

configuration
    properties
    settings
    typeAliases
    typeHandlers
    objectFactory
    plugins
    environments
        environment
            transactionManager
            dataSource
    mappers

一、properties元素

它们都是外部化,可替代的属性。可以配置在一个典型的 Java 属性文件中,或者通过 properties 元素的子元素进行配置。例如:

<properties resource="org/mybatis/example/config.properties">
    <property name="username" value="dev_user" />
    <property name="password" value="123456" />
<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>

示例中的 username 和 password 将会被替换为配置在 properties 元素中的相应值。driver 和 url 属性则会被 config.properties 文件中的相应值替换。这里提供了大量的配置选项。

这些属性也可以传递给 sqlSessionFactoryBuiIder() 方法。例如

SqlSessionFactory factory = sqlSessionFactoryBuiIder.build(reader, props);
// 或者
SqlSessionFactory factory = sqlSessionFactoryduilder.build(reader, environment, props),

如果一个属性存在于多个地方,将使用下的顺序加载:

  1. 首先读入 properties 元素主体中指定的属性。
  2. 然后会加载类路径或者 properties 元素中指定的 url 的资源文件属性。它会覆盖前面已经读入的同名属性。
  3. 通过方法参数来传递的属性将最后读取(即通过 sqlSessionFactoryBuilder.build),同样也会覆盖从 properties 元素指定的和 resource/url 指定的同名属性。

因此最优先的属性是通过方法参数来传递的属性,然后是通过 resource/url 配置的属性,最后是在 Mybatis 配置文件中,properties元素主体中指定的属性。

从 MyBatis 3.4.2 开始,你可以为占位符指定一个默认值。这部分不常用,参考官网说明。

二、Settings元素

Setting 元素下是些非常重要的设置选项,用于设置和改变 MyBatis 运行中的行为。下面的表格列出了 Setting 元素支持的属性、默认值及其功能。

设置选项

描述

可用值

默认值

cacheEnabled

全局性地启用或禁用所有在mapper配
置文件中配置的缓存。

true |
false

true

lazyLoadingEnabled

全局性地启用或禁用延迟加载。当禁用
时,所有关联的配置都会立即加载。

true |

false

true

aggressiveLazyLoading

当启用后,一个有延迟加载属性的对象
的任何一个延迟属性被加载时,该对象
的所有的属性都会被加载。否则,所有
属性都是按需加载。

true |

false

true

multipleResultSetsEnabled

允许或禁止从单一的语句返回多个结果
集(需要驱动程序兼容)。

true |

false

true

useColumnLabel

使用列的标签而不是列的名称。在这方
面,不同的驱动程序可能有不同的实
现。参考驱动程序的文档或者进行测试
来确定您所仗用的驱动的行为

true |

false

true 

useGeneratedKeys

允许JDBC白动生成主键。需要驱动程
序兼容力如果设置为true则会强行自
动生成主踺,然而有些则不会自动生成
主键(驱动程序不兼容),但依旧会工
作(如Derby)

true |

false

 false

autoMappingBehavior

指定MyBatis是否以及如何自动将列映
射到字段/属性。
PARTIAL:只是自动映射简单、非嵌套
的结果集。
FULL:将会自动映射任何复杂的(嵌套
或非朕套)的结果集。

NONE,
PARTIAL,
FULL

 PARTIAL

defaultExecutorType

配置默认的执行器(executor)
SIMPLE:简单的执行器。
REUSE:重用prepared statements的
执行器。
BATCH:重用statements并且进行批量
更新的执行器。

SIMPLE
REUSE
BATCH

 SIMPLE

defaultStatementTimeout

设置查询数库超时时间。

任何正整数

NotSet
(null)

一个 Settings 元素完整的配置例子如下:

<settings>
    <setting name="cacheEnabled" value="true"/>    
    <setting name="lazyLoadingEnabled" value="true"/>    
    <setting name="aggressiveLazyLoading" value="true"/>                
    <setting name="multipleResultSetsEnabled" value="true"/>        
    <setting name="useColumnLabel" value="true"/>        
    <setting name="useGeneratedKeys" value="false"/>        
    <setting name="autoMappingBehavior" value="PAETIAL"/>        
    <setting name="defaultExecutorType" value="SIMPLE"/>         
    <setting name="defaultStatementTimeout" value="25000"/>    
<settings>

三、typeAliases元素

别名是一个较短的 Java 类型的名称。这只是与 XML 配置文件相关联,减少输入多余的完整类名。例如:

<typeAliases>
    <typeAlias  alias="Author"  type="domain.blog.Author" />
    <typeAlias  alias="Blog"  type="domain.blog.Blog" />
</typeAliases>

在这个配置中,您就可以在想要使用 "domain.blog.Blog" 的地方使用别名 "Blog" 了。对常用的 Java 类型,已经内置了一些别名支持。这些别名都是不区分大小写的.注意 Java 的基本数据类型,它们进行了特别处理,加了 "_" 前缀。

别名

对应的 Java 类型

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

string

String

Byte

Byte

Long

Long

short

Short

Int

Integer

integer

Integer

double

Double

Float

Float

boolean

Boolean

Date

Date

decimal

BigDecimal

bigdecimal

BigDecimal

object

Object

Map

Map

hashmap

HashMap

List

List

arraylist

ArrayList

collection

Collection

iterator

Iterator

四、typeHandlers 元素

每当 Mybatis 设置参数到 PreparedStatement 或者从 ResultSet 结果集中取得值时,就会使用 TypeHandler 来处理数据库类型与 Java 类型之间转换。下表描述了默认的 TypeHandler。

java mapper xml 文件名一致 mapper.xml_ide

您能够重写类型处理器(type handlers),或者创建您自己的类型处理器去处理没有被支持的或非标准的类型。要做到这一点,只要实现接口(org.mybatis.type),并且将您的 TypeHandler 类映射到 java 类型和可选的 JDBC 类型即可。例如:

public class ExampleTypeHandler implements TypeHandler<String>{
    @Override
    public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, parameter);
    }
    @Override
    public String getResult(ResultSet rs, String columnName) throws SQLException {
        return rs.getString(columnName);
    }

    @Override
    public String getResult(ResultSet rs, int columnIndex) throws SQLException {
        return rs.getString(columnIndex);
    }

    @Override
    public String getResult(CallableStatement arg0, int arg1) throws SQLException {
        return null;
    }
}

使用上

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

使用上面的 TypeHandler 将会重写已经存在的用来处理 Java 的 String 属性、VARCHAR 参数和结果集的类型处理器。注意,MyBatis 并不会通过数据库的元数据来确认类型,所以您必须指定它的一个类型处理器,用于将 VARCHAR 字段的参数和结果映射到正确的类型上。这是因为 MyBatis 在语句的执行之前都不知道它要处理的数据类型是什么。

五、objectFactory 元素

MyBatis 每次创建一个结果对象实例都会使用 ObjectFactory 实例。使用默认的 ObjectFactory 与使用默认的构造函数(或含参数的构造函数)来实例化目标类没什么差别。如果您想重写 ObjectFactory 来改变其默认行为,那您能通过创造您自己的 ObjectFactory 来做到。看下面的例子:

public class ExampleObjectFactory extends DefaultObjectFactory{
    public Object create(Class type){
        return super.create(type);
    }
    
    public Object create(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs){
        return super.create(type, constructorArgTypes, constructorArgs);
    }
    
    public void setProperties(Properties properties){
        super.setProperties(properties);
    }
}

使用上

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

ObjectFactory 接口非常简单,它包含两个create的方法,一个是默认构造器,还有一个是含参数的构造器。最后的 setProperties 方法用来配置 ObjectFactory。在初始化您自己的 ObjectFactory 实例之后,定义在 ObjectFactory 元素主体中的属性会以参数的形式传递给 setProperties 方法。

六、Plugins元素

MyBatis允许您在映射语句执行的某些点拦截方法调用。默认情况下,MyBatis允许插件(plug-ins)拦截下面的方法:

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

通过寻找完整的方法特征能够发现这些类方法的细节,以及在每个 MyBatis 发布版本中的源代码中找到。假如您要做的不仅仅是监视方法的调用情况,您就应该清楚您将重写的方法的行为动作。如果您试图修改或者重写给定的方法,您很可能会改变 MyBatis 的核心行为。这些都是比较底层的类和方法,所以要小心使用插件。

@Intercepts({@Signature(type=Executor.class,method="update",args={MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor{

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // TODO Auto-generated method stub
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        // TODO Auto-generated method stub
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties arg0) {
    }
}

使用上

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

上面定义的插件将会拦截所有对 Executor 实例 update 方法的调用。Executor 实例是一个负责底层映射语句执行的内部对象。

重写配置类(Configuration Class)

除了能用插件方式修改 MyBatis 的核心行为,您也可以完全重写配置类(Configuration Class)。简单地扩展它和重写内部的任何方法,然后作为参数传递给 sqlSessionFactoryBuilder.build(myConfig) 方法。再次提醒,这可能对 MyBatis 行为产生严重影响,因此要小心。

七、Environments 元素

MyBatis  能够配置多套运行环境,这有助于将您的 SQL 映射到多个数据库上。例如,在您的开发、测试、生产环境中,您可能有不同的配置。或者您可能有多个共享同一 schema 的生产用数据厍,或者您想将相同的 SQL 映射应用到两个数据库等等许多用例。

但是请记住:虽然您可以配置多个运行环境,但是每个 SqlSessionFactory 实例只能选择一个运行环境。

因此,如果您想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,一个数据库对应一个 SqlSessionFactory 实例。如果是三个数据库,那就创建三个实例,如此类推。这真的非常容易记住:

每个数据库对应一个 SqlSessionFactory 实例。

要指定哪个运行环境被创建,只需要简单地将运行环境作为可选参数传递给 SqlSessionFactoryBuilder,下面是两个接受运行环境的方法:

SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader,environment);
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment, properties),

如果坏境参数被忽略,那默认的环境配置将被加载,如下面:

SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader);
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader,properties);

environments元素定义了运行坏境是怎么配置的:

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC" >
      <property name="..." value="..." />
    </transactionManager >
    <!-- 配置数据库连接信息 -->
    <dataSource type="POOLED">
      <property name="driver" value="oracle.jdbc.driver.OracleDriver" />
      <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl" />
      <property name="username" value="zzhc" />
      <property name="password" value="zzhc" />
    </dataSource>
  </environment>
</environments>

注意这里关键的部分:

  • 默认的运行环境ID,引用一个已经定义好的运行环境ID(例如:default="development")
  • 每个定义的运行环境ID(例如:id="development")
  • 事务管理器配置(例如:type="JDBC")
  • 数据源配置(例如:type="POOLED")

默认的环境和环境ID是自解(selfexplanatory)的,只要您喜欢,就可以随意取一个名字,只要确保默认的运行环境引用一个已定义的运行环境就可以了。

<environments default="test">
  <environment id="development">
    ......
  </environment>
    <environment id="production">
    ......
  </environment>
    <environment id="test">
    ......
  </environment>
</environments>

上面例子中,<environmentsdefault="test"> 配置表明,目前使用的是test的运行环境。当然,您也可以修改为使用 production 的运行环境:<environmentsdefault="production">。

八、事务管理器

MyBatis 有两种事务管理类型(即 type="[POOLED|MANAGED]")

1)JDBC:这个配置直接使用JDBC的提交和回滚能。它依赖于从数据源获得连接来管理事务的生命周期。

2)MANAGED:这个配置基本上什么都不做。它从不提交或者回滚一个连接的事务。而是让容器(例如:Spring 或者 J2EE 应用服务器)来管理事务的生命周期。默认情况下,它会关闭连接,但是一些容器并不会如此,因此,如果您需要通过关闭连接来停止事务,将属性 closeConnection 设置为 false。例如:

<transactionManager type="MANAGED" >
    <property name="closeConnection" value="false" />
</transactionManager>

这两个事务管理类型都不需要任何属性。然而它们都是类型别名,换句话说,您可以设置成指向己实现了 TransactionFactory 接口的完整类名或者别名。

public interface TransactionFactory{
    void setProperties(Properties props);
    Transaction newTransaction(Connection conn,boolean autoCommit);
}

实例化后,任何在XML文件配置的属性都将传递给 setProperties() 方法。在您的实现中还需要创建一个非常简单的 Transaction 接口的实现:

public interface Transaction{
    Connection getConnection();
    void commit() throws SQLException;
    void rollback() throws SQLException;
    void close() throws SQLException;
}

通过这两个接口,您能够完全自定义 MyBatis 如何来处理事务。

九、dataSource元素

dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源。

大部分 MyBatis 应用都像上面例子那样配置一个数据源,但这不是必须的。需要认清的是,只有使用了延迟加载才需要数据源。

MyBatis 内置了三种数据源类型(如:type="POOLED"):

1、UNPOOLED

这个类型的数据源实现只是在每次需要的时候简单地打开和关闭连接。虽然有点慢,但是对于不需要立即响应的简单的应用来说,不失为一种好的选择。不同的数据库在性能方面也会有所不同,因此对于一些数据库,不使用连接池时,这个配置就是比较理想的。

UNPOOLED 数据源有四个配置属性:

  • driver :指定 JDBC 驱动器。

  • url :连接数据库实例的JDBC URL。

  • username :登陆数据库的用户名。

  • password :登陆数据库的密码。

  • defaultTransactionIsolationLevel :指定连接的默认事务隔离级别。

另外,您也可以通过在属性前加前缀 "driver" 的方式,把属性传递给数据库驱动器,例如:

  • driver.encoding=UTF8

这将会通过 DriverManager.getConnection(url, driverProperties) 方法,将值是 "UTF8" 的属性 "encoding" 传递给数据库驱动器。

2、POOLED

这个数据源的实现缓存了JDBC连接对象,用于避免每次创建新的数据库连接时都初始化和进行认证,加快程序响应。并发 WEB 应用通常通过这种做法来获得快速响应。

另外,除了上面(UNPOOLED)的属性外,对 POOLED 数据源,还有很多属性可以设置。

  • poolMaximumActiveConnections :在任何特定的时间内激活(能够被使用)的连接数量,默认是10。

  • poolMaximumIdleConnections :在任何特定的时间内空闲的连接数。

  • poolMaximumCheckoutTime :在连接池被强行返回前,一个连接能够“检出”的总时间。默认是20000ms(20秒)。

  • poolTimeToWait :这是一上比较底层的设置,如果连接占用了很长时间,能够给连接池一个机会去打印日志,并重新尝试连接。默认是20000ms(20秒)。

  • poolPingQuery :PingQuery 是发送给数据库的 Ping 信息,测试数据库连接是否良好和是否准备好了接受请求。默认值是 "NOPINGQUERYSET",让大部分数据库都不使用 Ping,返回一个友好的错误信息(注:MyBatis 通过向数据执行 SQL 语句来确定与数据库连接状况)。

  • poolPingEnabled :这是允许或者禁 pingquery 的开关。如果允许,您同时也要用一条可用的(并且应该是最高效的)SQL语句来设置 poolPingQuery 属性的值。默认是:false(即禁止)。

  • poolPingConnectionsNotUsedFor :这个属性配置执行 poolPingQuery 的间隔时间。通常设置为与数据库连接的超时时间,来避免不必要的 pings。默认是:0(允许所有连接随时进行 ping 测试,当然只有 poolPingEnabled 设置为 true 才会生效)。

3、JNDI

这个数据源的配置是为了准备与像 Spring 或应用服务器能够在外部或者内部配置数据源的容器一起使用,然后在 JNDI 上下文中引用它。这个数据源只需配置两个属性:

  • initial_context :这个属性被用来从InitialContext中查找一个上下文。如:initialContext.lookup(initial_context) 这个属性是可选的,如果忽略,那么数据源就会直接从 InitialContext 中查找。

  •data_source :这个属性是引用一个能够被找到的数据源实例的上下文路径。它会查找根据 initial_context 从 initialContext 中搜寻返回的上下文。或者在 initial_context 没有提供的情况下直接在 InitialContext 中进行查找。

Contextcontext = (Context)initialContext.lookup(initial_context);//返回一个上下文
//Contextcontext = (Context)initContext.lookup("java:/comp/env");
DataSourceds = (DataSource)context.lookup(data_source);//返回一个数据源
Connectionconn = ds.getConnection();
//DataSourceds = (DataSource)context.lookup("jdbc/myoracle");

//如果initial_context没有配置,那么数据源就会直接从InitialContext进行查找,如:
DataSourceds = (DataSource)initialContext.lookup(data_source);

跟数据源的其它属性配置一样,可以通过在属性名前加 "env." 的方式直接传递给 InitialContext。例如:

  • env.encoding=UTF8

这将会把属性 "encoding" 及它的值 "UTF8" 在 InitialContext 实例化的时候传递给它的构造器。

十、Mappers元素

现在,MyBatis 的行为属性都已经在上面的配置元素中配置好了,接下来开始定义映射 SQL 语句。但首先,我们需要告诉 MyBatis 在哪里能够找到我们定义的映射 SQL 语句。在这方面,JAVA 自动发现没有提供好的方法,因此最好的方法是告诉 MyBatis 在哪里能够找到这些映射文件。您可以使用类资源路径或者 URL(包括 file:///URLs),例如:

//Usingclasspathrelativeresources
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
//Usingurlfullyqualifiedpaths
<mappers>
  <mapper url="file:///var/sqlmaps/AuthorMapper.xml"/>
  <mapper url="file:///var/sqlmaps/BlogMapper.xml"/>
  <mapper url="file:///var/sqlmaps/PostMapper.xml"/>
</mappers>

这些配置告诉 MyBatis 在哪里找到 SQL 映射文件。而其它的更详细的信息配置在每一个 SQL 映射文件里。