Mybatis学习笔记二——XML核心配置文件

一、核心配置文件概述

首先给出xml核心配置文件的组成部分,核心配置文件由头部生命和配置两个部分所组成,头部声明包含一下内容

<?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标签包裹,里面可以包含以下内容

  1. properties(属性)
  2. settings(设置)
  3. typeAliases(类型别名)
  4. typeHandlers(类型处理器)
  5. objectFactory(对象工厂)
  6. plugins(插件)
  7. environments(环境配置)
    7.1. environment(环境变量
    7.2 transactionManager(事务管理器)
  8. dataSource(数据源)
  9. databaseIdProvider(数据库厂商标识) mappers(映射器)

下面就对这些内容分别进行阐述

二、属性properties

2.1、数据动态读取

2.1.1、数据读取方式

这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件(*.properties文件)中配置这些属性,也可以在 properties 元素的子元素中设置。
举个例子,假设properties文件中进行了这样的设置

<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="dev_user"/>
  <property name="password" value="F2Fa3!33TYyg"/>
</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 文件中对应的值来替换。

通过构造函数的方式进行设置也是可以的

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, props);
// ... 或者 ...
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, props);

这里的reader是Reader类型的变量,environment是字符串,props是Properties类型的变量

2.1.2、数据读取优先级

三种设置方式的优先级为构造方法 > 文件中读取的 > property标签设置的,优先级低的值将被优先级高的值覆盖

2.2、占位符默认值的设置

从 MyBatis 3.4.2 开始,你可以为占位符指定一个默认值,采用的是冒号加默认值的方式。例如

<dataSource type="POOLED">
  <!-- ... -->
  <property name="username" value="${username:ut_user}"/> <!-- 如果属性 'username' 没有被配置,'username' 属性的值将为 'ut_user' -->
</dataSource>

如果要使用这个属性,需要在properties标签内部添加一个property标签进行配置,这是因为设定默认值的属性默认是关闭的

<properties resource="org/mybatis/example/config.properties">
  <!-- ... -->
  <property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/> <!-- 启用默认值特性 -->
</properties>

如果你在属性名中使用了 “:” 字符(如:db:username),或者在 SQL 映射中使用了 OGNL 表达式的三元运算符(如: ${tableName != null ? tableName : ‘global_constants’}),就需要设置特定的属性来修改分隔属性名和默认值的字符。例如:

<properties resource="org/mybatis/example/config.properties">
  <!-- ... -->
  <property name="org.apache.ibatis.parsing.PropertyParser.default-value-separator" value="?:"/> <!-- 修改默认值的分隔符 -->
</properties>
<dataSource type="POOLED">
  <!-- ... -->
  <property name="username" value="${db:username?:ut_user}"/>
</dataSource>

二、设置settings

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。
在这里插入图片描述

三、类型别名typeAliases

3.1、自定义类型别名

类型别名可为 Java 类型设置一个缩写名字。 它 仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:

<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>

当这样配置时,Blog 可以用在任何使用 domain.blog.Blog 的地方。
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:

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

每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author;若有注解,则别名为其注解值。见下面的例子:

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

3.2、Java 类型内建的类型别名

在这里插入图片描述

四、类处理器typeHandlers

类处理器主要是将JDBC取出的数据库类型转为Java类型
在这里插入图片描述
Mybatis也支持用户自定义类处理器。详情见官方文档。

五、对象工厂objectFactory

每次 MyBatis 创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成实例化工作。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。 如果想覆盖对象工厂的默认行为,可以通过创建自己的对象工厂来实现。比如:

// ExampleObjectFactory.java
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);
  }
  public <T> boolean isCollection(Class<T> type) {
    return Collection.class.isAssignableFrom(type);
  }}

使用如下配置

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

ObjectFactory 接口很简单,它包含两个创建实例用的方法,一个是处理默认无参构造方法的,另外一个是处理带参数的构造方法的。 另外,setProperties 方法可以被用来配置 ObjectFactory,在初始化你的 ObjectFactory 实例后, objectFactory 元素体中定义的属性会被传递给 setProperties 方法。

六、插件plugins

mybatis支持引入一些第三方的插件,比如分页插件

    <plugins>
        <!-- com.github.pagehelper.PageInterceptor -->
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <property name="helperDialect" value="mysql" />
            <property name="reasonable" value="true" />
        </plugin>
    </plugins>

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

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

当然Mybatis也是允许自定义插件的,官方文档中给出的模板是这样的: 这些类中方法的细节可以通过查看每个方法的签名来发现,或者直接查看
MyBatis 发行包中的源代码。 如果你想做的不仅仅是监控方法的调用,那么你最好相当了解要重写的方法的行为。
因为在试图修改或重写已有方法的行为时,很可能会破坏 MyBatis 的核心模块。 这些都是更底层的类和方法,所以使用插件的时候要特别当心。

通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定想要拦截的方法签名即可。

// ExamplePlugin.java
@Intercepts({@Signature(
  type= Executor.class,
  method = "update",
  args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
  private Properties properties = new Properties();
  public Object intercept(Invocation invocation) throws Throwable {
    // implement pre processing if need
    Object returnObject = invocation.proceed();
    // implement post processing if need
    return returnObject;
  }
  public void setProperties(Properties properties) {
    this.properties = properties;
  }
}

七、环境配置 environments

7.1、environments标签

环境主要针对将SQL映射应用到多种数据库之中,每一个数据库都拥有一个SqlSession实例,创建不同环境的SqlSession对象需要传递Environment实例对象,如下所示

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

如果忽略了默认参数,就按照默认的方式来加载

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);

Environment对象可以通过Java语句进行构造

public Environment(String id, TransactionFactory transactionFactory, DataSource dataSource) {
        if (id == null) {
            throw new IllegalArgumentException("Parameter 'id' must not be null");
        } else if (transactionFactory == null) {
            throw new IllegalArgumentException("Parameter 'transactionFactory' must not be null");
        } else {
            this.id = id;
            if (dataSource == null) {
                throw new IllegalArgumentException("Parameter 'dataSource' must not be null");
            } else {
                this.transactionFactory = transactionFactory;
                this.dataSource = dataSource;
            }
        }
    }

也可以通过配置的方式进行,下面给出了environment配置的典型例子

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    </transactionManager>
    <dataSource type="POOLED">
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
</environments>

environments标签内可以包含多个environment标签,每个标签代表了一种环境,通过设置enviroments标签中的default选项,可以设置默认的环境的id。每个environment标签的id通过id进行设置。

7.2、内部的environment标签

每一个environment标签又包括两个部分,分别是事务管理器transactionManager和数据源dataSource,下面就针对每一个小的标签进行阐述。

7.2.1、事务管理器transactionManager

事务管理器有两种类型,分别是JDBC和MANAGED

  • JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
  • MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。例如
<transactionManager type="MANAGED">
  <property name="closeConnection" value="false"/>
</transactionManager>

值得注意的是,如果使用了Spring + Mybatis框架,则不需要配置事务管理器,因为Spring自带的管理器会配置前面的事务管理器。
这两种事务管理器都不需要配置任何的property参数,因为TransactionFactory接口的setProperties方法是空的。如果想要对参数进行设置,可以采用同名实现类重写方法来实现。

7.2.2、数据源dataSource

dataSource数据源首先需要配置type,type有三种内建的数据类型,分别是POOLED、UNPOOLED、JNDI,下面对这三种内建数据类型进行介绍

UNPOOLDE

顾名思义就是不使用连接池的一种方式,可以用于连接可用性要求不高的业务,UNPOOLED需要配置五种属性

  • driver – 这是 JDBC 驱动的 Java 类全限定名(并不是 JDBC 驱动中可能包含的数据源类)。作为可选项,你也可以传递属性给数据库驱动。只需在属性名加上“driver.”前缀即可,例如:driver.encoding=UTF8
  • url – 这是数据库的 JDBC URL 地址。
  • username – 登录数据库的用户名。
  • password – 登录数据库的密码。
  • defaultTransactionIsolationLevel – 默认的连接事务隔离级别。
  • defaultNetworkTimeout – 等待数据库操作完成的默认网络超时时间(单位:毫秒)
    其中driver、url、username、password四个属性通常来讲是必须的

POOLED
使用连接池的方式,避免了创建新的连接实例时所必需的初始化和认证时间。 这种处理方式很流行,能使并发 Web 应用快速响应请求,除了上述四个属性之外,还有这几种属性可以进行配置

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

可以看出,这都是有关连接池属性的一些设置

JNDI
这是关于EJB或者应用服务器等的设置,用的比较少,这里就不再赘述了,用的时候可以看官方文档

八、数据库厂商标识 databaseIdProvider

MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 MyBatis 会加载带有匹配当前数据库 databaseId 属性和所有不带 databaseId 属性的语句。 如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃。 为支持多厂商特性,只要像下面这样在 mybatis-config.xml 文件中加入 databaseIdProvider 即可:

<databaseIdProvider type="DB_VENDOR" />

databaseIdProvider 对应的 DB_VENDOR 实现会将 databaseId 设置为 DatabaseMetaData#getDatabaseProductName() 返回的字符串。 由于通常情况下这些字符串都非常长,而且相同产品的不同版本会返回不同的值,你可能想通过设置属性别名来使其变短:

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

设置好了之后就可以在映射配置文件当中通过设置databaseId来选择不同的sql语句了,比如下面这样

  <select id="SelectTime"   resultType="String" databaseId="mysql">
   SELECT  NOW() FROM dual 
  </select>
  <select id="SelectTime"   resultType="String" databaseId="oracle">
   SELECT  'oralce'||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss')  FROM dual 
  </select>

程序会根据启用的数据库的不同来选择不同的语句执行

九、映射器Mappers

我们现在就要来定义 SQL 映射语句了。 但首先,我们需要告诉 MyBatis 到哪里去找到这些语句。映射器Mappers标签内可以有多个Mapper标签来指向不同的资源,资源的指向方式有4种:类路径资源引用、完全限定资源路径引用、实现类内容引用、实现类的包的内容引用,后两种主要针对注解形式的sql语句,这个后面会说到,先展示以下这四种资源的引入方式

<!-- 使用相对于类路径的资源引用 -->
<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>

十、总结

可以看到,environments标签和mappers标签两项是必须拥有的,因为他们一个关乎与数据库连接,一个关乎从数据库得到数据并将其映射到domain对象当中,而其他标签下的内容要么存在有默认值,不必要的时候可以不设置,要么属于辅助性的一些内容。
因此在编写Mybatis核心配置文件的过程中可以先写environments标签以便Mybatis与数据库连接,再编写mappers标签完成映射,其他标签按需取。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值