https://mybatis.org/mybatis-3/zh/configuration.html#properties
MyBatis的配置文件包含了影响MyBatis行为甚深的设置(settings)和属性(properties)信息。文档的顶层结构如下:

  1. --configuration配置
  2. --properties属性
  3. --setting设置
  4. --typeAliases类型命名
  5. --typeHandlers类型处理器
  6. --objectFactory对象工厂
  7. --plugins插件
  8. --environments环境
  9. --environment环境变量
  10. --transactionManager事务管理器
  11. --dataSource数据源
  12. --databaseIdProvider数据库厂商标识
  13. --mappers映射器

properties属性

  1. driver=comjdbc.driver=com.mysql.cj.jdbc.Driver
  2. jdbc.url=jdbc:mysql://localhost:3306/mybatis
  3. jdbc.username=root
  4. jdbc.password=root
<properties resource="dbconfig.properties"></properties>

如果属性在不止一个地方进行了配置,那么MyBatis将按照下面的顺序来加载:

  1. 在properties元素体内指定的属性首先被读取。
  2. 然后根据properties元素中的resource属性读取类路径下属性文件或根据url属性指定的路径读取属性文件,并覆盖已读取的同名属性。
  3. 最后读取作为方法参数传递的属性,并覆盖已读取的同名属性。
<dataSource type="POOLED">
    <property name="driver" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</dataSource>

settings设置

这是MyBatis中极为重要的调整设置,他们会改变myBatis的运行时行为

设置参数 描述 有效值 默认值
cacheEnabled 该配置影响的所有映射器中配置的缓存的全局开关 true|false TRUE
lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有管理对象都会延迟加载,特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态 true|false FALSE
useColumnLabel 使用列标签代替列名,不同的驱动在这方面会有不同的表现,具体可以参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。 true|false TRUE
defaultStatementTimeout 设置查实时间,他决定驱动等待数据库相应的秒数 Any positive integer Not Set(null)
mapUnderscoreToCamelCase 是否开启自动多封命名规则(camel case)映射,即从经典数据库列名A_COLUMN到经阿丹Java属性名aColumn的类似映射 true|false FALSE
<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--
    2. settings包含了很多重要的设置项
    setting:用来设置每一个设置项
-->
<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

typeAliases别名处理器

  1. 类型别名是为Java类型设置一个短的名字,可以方便我们引用某个类。

    <typeAliases>
     <typeAlias type="com.zh.bean.Employee" alias="employee"/>
     <typeAlias type="com.zh.bean.Department" alias="department"/>
    </typeAliases>
    
  2. 类似很多的情况下,可以批量设置别名这个包下的每一个类默认创建一个默认的别名,就是简单类名小写。

    <typeAliases>
     <package name="com.zh.bean"/>
    </typeAliases>
    
  3. 也可以使用@Alias注解为其指定一个别名

    @Alias("emp")
    public class Employee{}
    
  4. 值得注意的是,MyBatis已经为许多常见的Java类型内建了响应的类型别名。他们都是大小写不敏感的,我们在起别名的时候千万不要占有已有的别名。 | 别名 | 映射的类型 | | —- | —- | | _byte | byte | | _long | long | | _short | short | | _int | int | | _interger | 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 | | colletion | Collection | | iterator | Iterator |

<!--
    3. typeAliases:别名处理器,可以为我们的java类型起别名
        别名不区分大小写
-->
<typeAliases>
    <!-- typeAlias:为某个java类型起别名
            type: 指定要起别名的类型全类名;默认别名 类名小写:employee
            alias: 指定新的别名
     -->
    <!--<typeAlias type="com.zh.mybatis.bean.Employee" alias="emp"/>-->


    <!--
        package:为每个报下的所有类批量起别名
            name:指定包名(为当前包以及下面所有的后代包的每一个类都起一个默认别名(类名小写),)
    -->
    <package name="com.zh.mybatis.bean"/>

    <!--
        批量起别名的情况下,使用@Alias注解为某个类型指定新的别名
    -->
</typeAliases>

typeHandlers类型处理器

无论是MyBatis在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换成java类型

类型处理器 Java类型 JDBC类型
BooleanTypeHandler java.lang.Boolean,boolean 数据库兼容的Boolean
ByteTypeHandler java.lang.Byte,byte 数据库兼容的NUMERIC或BYTE
ShortTypeHandler java.lang.Short, short 数据库兼容的 NUMERIC 或 SHORT INTEGER
IntegerTypeHandler java.lang.Integer, int 数据库兼容的 NUMERIC 或 INTEGER
LongTypeHandler java.lang.Long, long 数据库兼容的 NUMERIC 或 LONG INTEGER
FloatTypeHandler java.lang.Float, float 数据库兼容的 NUMERIC 或 FLOAT
DoubleTypeHandler java.lang.Double, double 数据库兼容的 NUMERIC 或 DOUBLE
BigDecimalTypeHandler java.math.BigDecimal 数据库兼容的 NUMERIC 或 DECIMAL
StringTypeHandler java.lang.String CHAR, VARCHAR

日期类型的处理

  1. 日期和时间的处理,JDK1.8以前一直是个头疼的问题。我们通常使用JSR310规范领导者Stephen Colebourne创建的Joda-Time来操作。1.8已经实现了全部的JSR310规范了。
  2. 日期时间处理上,我们可以使用MyBatis基于JSR310(Date and Time API )编写的各种日期时间类型处理器。
  3. MyBatis3.4以前的版本需要我们手动注册这些处理器,以后的版本都是自动注册的。

image-20200923143657422.png

自定义类型处理

  1. 我们可以重写类型处理器或创建自己的类型处理器来处理不支持的非标准的类型。
  2. 步骤:
    1. 实现org.apache.ibatis.type.TypeHandler接口或者继承org.apache.ibatis.type.BaseTypeHandler
    2. 指定其映射某个JDBC类型(可选操作)
    3. 在mybatis全局配置文件中注册

plugins插件

  1. 插件是MyBatis提供的一个非常强大的机制,我们可以通过插件来修改MyBatis的一些核心行为。插件通过动态代理机制,可以介入四大对象的任何一个方法的执行。
  2. Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  3. ParameterHandler (getParameterObject, setParameters)
  4. ResultSetHandler (handleResultSets, handleOutputParameters)
  5. StatementHandler (prepare, parameterize, batch, update, query)

environments环境

  1. MyBatis可以配置多种环境,比如开发、测试和声场环境需要有不同的配置。
  2. 每种环境使用一个environment标签进行配置并制定唯一标识符
  3. 可以通过environments标签中的default属性指定一个环境的标识符来快速的切换环境
<!--
    4. environments,环境们,mybatis可以配置多种环境,default指定使用某种环境,可以达到快速切换的效果
        environment:配置一个环境信息:必须有两个标签;id代表当前环境的唯一标识
            transactionManager:事务管理器
                type:事务管理器的类型:JDBC(JdbcTransactionFactory)|MANAGED(ManagedTransactionFactory)
                    自定义事务管理器:TransactionFactory接口,type指定为全类名
            dataSource:数据源
                type:数据源的类型:UNPOOLED(UnpooledDataSourceFactory)|POOLED(PooledDataSourceFactory)|JNDI(JndiDataSourceFactory)
                    自定义数据源:实现DataSourceFactory接口,type是全类名
-->
<environments default="development">
    <environment id="test">
        <transactionManager type="JDBC"></transactionManager>
        <dataSource type="POOLED">
            <property name="driver" value="${jdbc.driver}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        </dataSource>
    </environment>

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

environment-指定具体环境

  1. id:指定当前环境的唯一标识
  2. transactionManager、和dataSource都必须有
<environments default="development">
    <environment id="development">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <property name="driver" value="${jdbc.driver}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        </dataSource>
    </environment>
</environments>

transactionManager

type:JDBC|MANAGED|自定义

  1. JDBC:使用了JDBC的提交和回滚设置,依赖于从数据源得到的连接来管理事务范围。JdbcTransactionFactory
  2. MANAGED:不提交或回滚一个连接、让容器来管理事务的整个生命周期(比如JEE应用服务器的上下文)。ManagedTransactionFactory
  3. 自定义:实现TransactionFactory接口,type=全类名/别名

dataSource

type:UNPOOLED|POOLED|JNDI|自定义

  1. UNPOOLED:不使用连接池,UNPOOLEDDataSourceFactory。
  2. POOLED:使用连接池,PooledDataSourceFactory
  3. JNDI:在EJB或应用服务器这类容器中查找指定的数据源。
  4. 自定义:实现DataSourceFactory接口,定义数据源的获取方法。
  5. 实际开发中我们使用Spring管理数据源,并进行事务控制的配置来覆盖上述配置

databaseIdProvider环境

  1. MyBatis可以根据不同的数据库厂商执行不同的语句。

    <databaseIdProvider type="DB_VENDOR">
     <property name="MySQL" value="mysql"/>
     <property name="Oracle" value="oracle"/>
     <property name="SQL Server" value="sqlServer"/>
    </databaseIdProvider>
    
  2. Type:DB_VENDOR

    1. 使用MyBatis提供的VendorDatabaseIdProvider解析数据库厂商标识。也可以实现DatabaseIdProvider接口来自定义。
  3. Property-name:数据库厂商标识
  4. Property-value:为标识起一个别名,方便SQL语句使用databaseId属性引用。

    <select id="getEmpById" resultType="employee">
     select * from tbl_employee where id = #{id}
    </select>
    <select id="getEmpById" resultType="employee" databaseId="mysql">
     select * from tbl_employee where id = #{id}
    </select>
    <select id="getEmpById" resultType="employee" databaseId="oracle">
     select * from tba_employee where id = #{id}
    </select>
    
  5. DB_VENDOR

    1. 会通过DatabaseMetaData#getDatabaseProductName()返回的字符串进行设置。由于通常情况下这个字符串都非常厂而且相同产品的不同版本会返回不同的值,所以最好通过设置属性别名来使其变短
      <!--
      5. databaseIdProvider :支持多数据库厂商
      type="DB_VENDOR":VendorDatabaseIdProvider
        作用:得到数据库厂商的标识(驱动getDatabaseProductName()),mybatis就能根据数据库厂商来执行不同的sql;
        MySQL,Oracle,SQL Server,xxxx
      -->
      <databaseIdProvider type="DB_VENDOR">
      <!--为不同的数据库厂商起别名-->
      <property name="MySQL" value="mysql"/>
      <property name="Oracle" value="oracle"/>
      <property name="SQL Server" value="sqlServer"/>
      </databaseIdProvider>
      

MyBatis匹配规则如下

  1. 如果没有配置databaseIdProvider标签,那么databaseId=null
  2. 如果配置了databaseIdProvider标签,使用标签配置的name去匹配数据库信息,匹配上设置databaseId=配置指定的值,否则依旧为null
  3. 如果databaseId不为null,他只会找到配置databaseId的sql语句
  4. MyBatis会加载不带databaseId属性和带有匹配当前数据库databaseId属性的所有语句。如果同时找到带有databaseId和不带databaseId的相同语句,则后者会被舍弃。

mapper映射

<!--将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中-->
<!--
    6. mappers:将sql映射注册到全局配置中
-->
<mappers>
    <!--
        mapper:注册一个sql映射
            注册配置文件
            resource:引用类路径下的sql映射文件
                mybatis/mapper/EmployeeMapper.xml
            url:引用网络路径下面的或磁盘路径下的sql映射文件
                file:///var/mappers/AuthorMapper.xml
            class:引用(注册)接口
                1. 有sql映射文件,映射文件名必须和接口同名,并且放在同一目录下:
                2. 没有sql映射文件,所有的sql都是利用注解写在接口上。
                推荐,比较重要的,复杂的Dao接口,我们来写sql映射文件,
                    不重要的,简单地Dao接口为了快速开发,我们可以使用注解。
    -->
<!--        <mapper resource="EmployeeMapper.xml"/>-->
<!--        <mapper class="com.zh.mybatis.dao.EmployeeMapperAnnotation"/>-->

    <!--批量注册-->
    <package name="com.zh.mybatis.dao"/>

</mappers>

mapper逐个注册SQL映射文件

<mappers>
    <mapper resource="mybatis/mapper/PersonDao.xml"/>
    <mapper url="file:///D:/UserDao.xml"/>
    <mapper class="com.zh.dao.PersonDapAnnotation"/>
</mappers>

或者使用批量注册

这种方式要求SQL映射文件名必须和接口名相同并且在同一目录下

<mappers>
    <package name="com.zh.dao"/>
</mappers>