MyBatis全局配置文件详解

MyBatis使用过程中主要需要配置两个xml文件,一个是全局配置文件,另一个是SQL映射文件。本片博文我们就来学习一下MyBatis的全局文件的使用配置方式。在官方文档中也有详细的解释:MyBatis全局配置文件的官方文档。通过看文档和写代码来学习全局配置文件的使用,全局配置文件的配置主要有以下:

这些子元素的配置是有顺序的,只能按照上面的顺序配置。可缺省部分子元素。

1、properties

properties提供了一个通过外部配置文件(例如数据库配置文件)来动态配置环境的方法。以动态配置数据库为例:

数据库配置文件jdbc.properties的详细配置如下:

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/xust?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true&set global time_zone='+8:00' 
username=root
password=95162437

那么我们可以在mybatis-config.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>

    <!--配置外部数据库文件的位置,把它加载进来--> 
    <properties resource="jdbc.properties">
    </properties>
    
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
             <!--通过在外部动态配置的方式来配置-->
             <!--需要注意的是value后面的值如果没有自定义,必须和外部配置文件中的名字一致-->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/StudentMapper.xml"/>
    </mappers>


</configuration>

2、settings

setting可以调整MyBatis的一些重要的配置,它们会改变 MyBatis 的运行时的行为,具体都有哪些配置可以设置可以参考官网,这里不再赘述,这里说几个常用的:

设置名描述有效值默认值
cacheEnabled全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。true | falsetrue
lazyLoadingEnabled延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。true | falsefalse
aggressiveLazyLoading开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载(参考 lazyLoadTriggerMethods)。true | falsefalse (在 3.4.1 及之前的版本中默认为 true)
multipleResultSetsEnabled是否允许单个语句返回多结果集(需要数据库驱动支持)。true | falsetrue
useColumnLabel使用列标签代替列名。实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档,或通过对比测试来观察。true | falsetrue
useGeneratedKeys允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)。true | falseFalse
autoMappingBehavior指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。NONE, PARTIAL, FULLPARTIAL
autoMappingUnknownColumnBehavior指定发现自动映射目标未知列(或未知属性类型)的行为。NONE: 不做任何反应WARNING: 输出警告日志('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior'的日志等级必须设置为 WARNFAILING: 映射失败 (抛出 SqlSessionException)NONE, WARNING, FAILINGNONE
defaultExecutorType配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(PreparedStatement); BATCH 执行器不仅重用语句还会执行批量更新。SIMPLE REUSE BATCHSIMPLE
defaultStatementTimeout设置超时时间,它决定数据库驱动等待数据库响应的秒数。任意正整数未设置 (null)
defaultFetchSize为驱动的结果集获取数量(fetchSize)设置一个建议值。此参数只可以在查询设置中被覆盖。任意正整数未设置 (null)
defaultResultSetType指定语句默认的滚动策略。(新增于 3.5.2)FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(等同于未设置)未设置 (null)
safeRowBoundsEnabled是否允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为 false。true | falseFalse
safeResultHandlerEnabled是否允许在嵌套语句中使用结果处理器(ResultHandler)。如果允许使用则设置为 false。true | falseTrue
mapUnderscoreToCamelCase是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。true | falseFalse
localCacheScopeMyBatis 利用本地缓存机制(Local Cache)防止循环引用和加速重复的嵌套查询。 默认值为 SESSION,会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地缓存将仅用于执行语句,对相同 SqlSession 的不同查询将不会进行缓存。SESSION | STATEMENTSESSION
jdbcTypeForNull当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型。 某些数据库驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。JdbcType 常量,常用值:NULL、VARCHAR 或 OTHER。OTHER
lazyLoadTriggerMethods指定对象的哪些方法触发一次延迟加载。用逗号分隔的方法列表。equals,clone,hashCode,toString
defaultScriptingLanguage指定动态 SQL 生成使用的默认脚本语言。一个类型别名或全限定类名。org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
defaultEnumTypeHandler指定 Enum 使用的默认 TypeHandler 。(新增于 3.4.5)一个类型别名或全限定类名。org.apache.ibatis.type.EnumTypeHandler
callSettersOnNulls指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这在依赖于 Map.keySet() 或 null 值进行初始化时比较有用。注意基本类型(int、boolean 等)是不能设置成 null 的。true | falsefalse
returnInstanceForEmptyRow当返回行的所有列都是空时,MyBatis默认返回 null。 当开启这个设置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集(如集合或关联)。(新增于 3.4.2)true | falsefalse
logPrefix指定 MyBatis 增加到日志名称的前缀。任何字符串未设置
logImpl指定 MyBatis 所用日志的具体实现,未指定时将自动查找。SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING未设置
proxyFactory指定 Mybatis 创建可延迟加载对象所用到的代理工具。CGLIB | JAVASSISTJAVASSIST (MyBatis 3.3 以上)
vfsImpl指定 VFS 的实现自定义 VFS 的实现的类全限定名,以逗号分隔。未设置
useActualParamName允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,你的项目必须采用 Java 8 编译,并且加上 -parameters 选项。(新增于 3.4.1)true | falsetrue
configurationFactory指定一个提供 Configuration 实例的类。 这个被返回的 Configuration 实例用来加载被反序列化对象的延迟加载属性值。 这个类必须包含一个签名为static Configuration getConfiguration() 的方法。(新增于 3.2.3)一个类型别名或完全限定类名。未设置
shrinkWhitespacesInSqlRemoves extra whitespace characters from the SQL. Note that this also affects literal strings in SQL. (Since 3.5.5)true | falsefalse

Mybatis中可配置的settings如下:

 <!--一些有关于mybatis运行是行为的设置-->
<settings>
	<setting name="cacheEnabled" value="true"/>
	<setting name="lazyLoadingEnabled" value="true"/>
	<setting name="multipleResultSetsEnabled" value="true"/>
	<setting name="useColumnLabel" value="true"/>
	<setting name="useGeneratedKeys" value="false"/>
	<setting name="autoMappingBehavior" value="PARTIAL"/>
	<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
	<setting name="defaultExecutorType" value="SIMPLE"/>
	<setting name="defaultStatementTimeout" value="25"/>
	<setting name="defaultFetchSize" value="100"/>
	<setting name="safeRowBoundsEnabled" value="false"/>
	<setting name="mapUnderscoreToCamelCase" value="true"/>    <!--设置数据库字段的下换线自动映射到java的驼峰模式-->
	<setting name="localCacheScope" value="SESSION"/>
	<setting name="jdbcTypeForNull" value="OTHER"/>
	<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

注意:settings、properties这些标签配置的位置不是随便的,他们的位置必须放在environment标签之前!

3、typeAliase

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

3.1 给单独的一个类重命名
<typeAliases>
  <typeAlias alias="Employee" type="com.xzy.bean.Employee"/>
</typeAliases>

这样做后,以后在程序中任何使用com.xzy.bean.Employee的地方都可以用Employee来代替,例如:

在mybatis-config.xml中添加如下配置:
<typeAliases>
   <!--给com.xzy.bean.Employee重命名为Employee-->
   <typeAlias type="com.xzy.bean.Employee" alias="Employee"/>
</typeAliases>

那么,在EmpoyeeMapper.xml中可以这么用:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xzy.mapper.EmployeeMapper">

     <!--原本这个地方的参数类型应该写成com.xzy.bean.Employee,由于重命名了可以直接使用重命的名子-->
    <insert id="add" parameterType="Employee" >
        insert into employee(emp_id,emp_name,emp_age,emp_sex) values(#{empId},#{empName},#{empAge},#{empSex})
    </insert>

    <delete id="delete" parameterType="int">
        delete from employee where id=#{id}
    </delete>

    <!--更新-->
    <update id="update" >
        update employee set  emp_id=#{param2.empId},emp_name=#{param2.empName},emp_age=#{param2.empAge},emp_sex=#{param2.empSex} where id=#{param1}
    </update>

    <select id="get" parameterType="int" resultType="Employee">
      select * from employee where id=#{id}
    </select>

    <select id="getAll" resultType="Employee">
        select * from employee
    </select>

</mapper>
3.2 给整个包重命名

使用package元素:

<typeAliases>
  <package name="com.xzy.bean"/>
</typeAliases>

       这样一来每一个在包 com.xzy.bean中的 Java Bean,在没有注解的情况下,会使用类名的首字母小写来作为它的别名。如果使用了注解,那就以注解为他的别名。

3.3 @Alias(name)注解给一个Java Bean重命名

其中name就是你给这个JavaBean起的别名

4、TypeHandler—类型处理器

无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。Mytais给了很多的类型处理器来实现java类型到数据库类型的转换,但是就是这样内置的类型处理器还是无法完全胜任,因此MyBatis允许我们重写类型处理器或创建自己的类型处理器来处理不支持的或非标准的类型。 具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承类 org.apache.ibatis.type.BaseTypeHandler, 然后可以选择性地将它映射到一个 JDBC 类型。 比如,有一个Phone类型:

package com.xzy.bean;

public class Phone {

    private String pre;   //手机的前缀
    private String num;   //手机号码


    public Phone(){}

    public Phone(String num){
        this.num=num;
    }

    public Phone(String pre,String num){
        this.pre=pre;
        this.num=num;
    }
  
     //省略getter、setter...

    @Override
    public String toString() {
        return "Phone{" +
                "pre='" + pre + '\'' +
                ", num='" + num + '\'' +
                '}';
    }
}

在另一个javaBean中使用他:

package com.xzy.bean;

public class Employee {

    private Long id;
    private String empId;
    private String empName;
    private int empAge;
    private String empSex;
    private  Phone phone;    //phone类型,他在MyBatis转换的时候肯定会出错的,因为数据库中没有Phone这种类型,那么这时候就需要自定义类型处理器了

   //省略getter、setter....

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", empId='" + empId + '\'' +
                ", empName='" + empName + '\'' +
                ", empAge=" + empAge +
                ", empSex='" + empSex + '\'' +
                '}';
    }
}
自定义类型处理器

自定义一个类型处理器,让他实现Typehandler接口,这个接口有一个泛型,这个参数就是处理后需要的java中对应对类型。

package com.xzy.typeHandler;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

import java.sql.*;

/**
 * Phone的类型处理
 */
public class PhoneHandler implements TypeHandler<String> {

    //设置参数
    @Override
    public void setParameter(PreparedStatement ps, int i, String phone, JdbcType jdbcType) throws SQLException {
        ps.setString(i,phone);
    }

    
    /*********下面的都是得到参数**********/
    @Override
    public String getResult(ResultSet res, String s) throws SQLException {
        return res.getString(s);
    }

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

    @Override
    public String getResult(CallableStatement call, int i) throws SQLException {
        return call.getString(i);
    }
}

在mybatis-config.xml中注册这个类型处理器 注册的方式有两种,一种是使用<typeHandler handler=""/>这个标签,在handler属性中执行处理器的全类名;另一种方式是直接使用<packge name=""/>标签在name属性中指定包名,然后整个包下的处理器都会被自动注册。具体如下:

<typeHandlers>
<!--1.单个处理器注册-->
  <typeHandler handler="com.xzy.handler.PhoneHandler"/>
</typeHandlers>

<!--或者这样:-->
<typeHandlers>
<!--2.直接把这个包名注册-->
  <package name="com.xzy.handler"/>
</typeHandlers>

5、配置环境(environments)

MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。 不过要记住:尽管可以配置多个环境,但是每个 SqlSessionFactory 实例只能选择其一。 环境配置实例:

<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>
5.1 事务管理器(transactionManager)

在 MyBatis 中有两种类型的事务管理器(也就是 type=”[JDBC|MANAGED]”):

  • JDBC – 这个配置就是直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
  • MANAGED – 这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期
5.1 数据源(dataSource)

dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。有三种内建的数据源类型(也就是 type=”[UNPOOLED|POOLED|JNDI]”):

  • UNPOOLED– 这个数据源的实现只是每次被请求时打开和关闭连接。这就是每次操作就要和数据库发生物理连接,数据会慢很多。
  • 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这种方式每次需要和数据可连接的时候就直接去连接池中去拿。
  • 这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。

通过需要实现接口 org.apache.ibatis.datasource.DataSourceFactory , 也可使用任何第三方数据源:

public interface DataSourceFactory {
  void setProperties(Properties props);
  DataSource getDataSource();
}

6、映射器(mappers)

mappers的作用就是告诉mybatis去哪里找SQL语句,因此对他的配置是至关重要。mybatis提供了如下4种配置的方法:

6.1 使用resource配置
<!-- 使用 resource -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
6.2 使用文件路径配置
<!-- 使用文件路径url -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
6.3 使用class属性配置接口配置单个mapper接口
<!-- 使用接口的全部类名 class -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
6.4 使用name属性注册一个包下的所有mapper接口
<!-- 使用name 注册一个包下的所有mapper接口 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

至此对于mybatis的全局配置大致完成了,接下来就是对SQL映射文件的配置了。

留言区

还能输入500个字符