MyBatis实战之配置

MyBatis最重要的配置也就两个,一个是mybatis-config.xml,又称MyBatis的全局配置,另一个就是XXXDao.xml或XXXMapper.xml映射配置。

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>
<typeAliases>
    <package name="com.blog.entity"/>
</typeAliases>


  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
      
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/blog_test"/>
        <property name="username" value="root"/>
        <property name="password" value="1234"/>
      </dataSource>
    </environment>
  </environments>
  
  <mappers>
    <mapper resource="mybatis/mapping/UserDao.xml"/>
  </mappers>
</configuration>

 

1.properties元素

properties是一个配置属性的元素,让我们能在配置文件的上下文使用它。

MyBatis提供3种配置方式。

(1)properties子元素(如上述);

(2)properties配置文件(例如读取jdbc.properties配置文件,这个在spring-mybatis整合得以体现);

(3)程序参数传递(本质上是读取properties配置文件,通过键值对的读取并传递参数);

 

关于它们的优先级

首先,properties元素体内指定的属性首先被读取;

其次,根据properties元素中的resource属性读取类路径下属性文件,或者根据url属性指定的路径读取属性文件,并覆盖已读取的同名属性;

最后,读取作为方法参数传递的属性,并覆盖已读取的同名属性;

因此,通过方法参数传递的属性具有最高优先级,resource/url属性中指定的配置文件次之,最低优先级的是properties属性中指定的属性。因此,实际操作中我们需要注意以下三点:

(1)不要使用混合的方式,这样会使得管理混乱;

(2)首先方式是使用properties文件;

(3)如果我们需要对其进行加密或者其他加工以满足特殊的要求,不妨按照程序参数传递方式;

 

 

2.设置

设置(settings)在MyBatis中是最复杂的配置,同时也是最为重要的配置内容之一,它会改变MyBatis运行时的行为。即使不配置settings,MyBatis也可以正常的工作,不过了解settings的配置内容,以及它们的作用仍然十分必要。

 

Settings的配置内容如下图所示:

图一:

 

图二:

 

 

 图三:

 

图四:

 

 

图五:

 

 

图六:

 

配置一般情况下不需要修改太多,只仅仅修改少量就行。

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="defaultExecutorType" value="SIMPLE" /> 
<setting name="defaultStatementTimeout" value="25000" /> 
<setting name="safeRowBoundsEnabled" value="false" /> 
<setting name="mapUnderscoreToCamelCase" value="false" /><setting name="localCacheScope" value="SESSION" /> 
<setting name="jdbcTypeForNull" value="OTHER" /> 
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode ,toString" />

 

3.别名

MyBatis系统定义了一些经常使用的类型的别名,例如,数值、字符串、日期和集合等,我们可以在MyBatis中直接使用它们,在使用时不要重复定义把它们给覆盖了。

让我们看看MyBatis已经定义好的别名(支持数组类型的只要加"[]" 即可使用,比如Date数组别名可以用date[]代替)。

系统定义的typeAliases 如图所示:

图一:

 

 图二:

 

图三:

 

我们在MyBatis实战之初步 说到过别名和它的三种配置方式,所以此处不再赘述。

 

4.typeHandler类型处理器

MyBatis在预处理语句(PreparedStatement)中设置一个参数时,或者从结果集(ResultSet)中取出一个值,都会用注册了的typeHandler进行处理。

由于数据库可能来自不同厂商,不同的厂商设置的参数可能存在差异,同时数据库也可以自定义数据类型,typeHandler允许根据项目的需要自定义设置Java传递到数据库的参数中,或者从数据库读出数据,我们也需要进行特殊的处理,这些都可以在定义的typeHandler中处理,尤其在使用枚举的时候我们常常需要使用typeHandler进行转换。

typeHandler和别名一样,分为MyBatis系统定义和用户自定义两种。一般来说,使用MyBatis系统定义就可以实现大部分的功能,如果使用用户自定义的typeHandler,我们在处理的时候务必小心谨慎,以避免出现不必要的错误。

typeHandler 常用的配置为Java类型(javaType)、JDBC类型(jdbcType)。typeHandler的作用就是将参数从javaType转化为jdbcType,或者从数据库取出结果时把jdbcType转化为javaType。

 

系统注册的typeHandle简介,如下图所示:

图一:

 

图二:

 

 需要注意以下几点?

(1)数值类型的精度,数据库Int、double、decimal这些类型和Java的精度、长度都是不一样的;

(2)时间精度,取数据到日用DateOnlyTypeHandler即可,用到精度为秒的用SqlTimestamp、TypeHandler等;

 

让我们选取一个MyBatis系统自定义的typeHandler,并了解它的具体内容。我们可以看到MyBatis源码包org.apache.ibatis.type下面定义的StringTypeHandler。StringTypeHandler是一个常用的typeHandler,负责处理String类型。

 

StringTypeHandler源码如下:

 *    Copyright 2009-2015 the original author or authors.
package org.apache.ibatis.type;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author Clinton Begin
 */
public class StringTypeHandler extends BaseTypeHandler<String> {

  @Override
  public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
      throws SQLException {
    ps.setString(i, parameter);
  }

  @Override
  public String getNullableResult(ResultSet rs, String columnName)
      throws SQLException {
    return rs.getString(columnName);
  }

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

  @Override
  public String getNullableResult(CallableStatement cs, int columnIndex)
      throws SQLException {
    return cs.getString(columnIndex);
  }
}

 

 说明一下上面的代码:

StringTypeHandler继承BaseTypeHandler,而BaseTypeHandler实现接口typeHandler,并且自己定义了4个抽象的方法。所以继承它的时候,正如本例一样,正如本例一样需要实现其定义的4个抽象方法,这些方法已经在StringTypeHandler中用@Override注解注明了。

setParameter是PreparedStatement对象设置参数,它允许我们自己填写变换规则。

getResult则分为ResultSet用列名(columnName)或者使用列下标(columnIndex)来获取结果数据。其中还包括了用CallableStatement(存储过程)获取结果及数据的方法。

 

如果你想自定义Handler,除了编写一个Java类之外,还需要在mybatis-config.xml配置如下内容:

  <typeHandlers>
  <typeHandler handler="com.blog.typehandler.MyStringHandler" javaType="string" jdbcType="varchar"/>
  </typeHandlers>

 

5.ObjectFactory

当MyBatis在构建一个结果返回的时候,都会使用ObjectFactory(对象工厂)去构建POJO,在MyBatis中可以定制自己的对象工厂。一般来说我们使用默认的ObjectFactory即可,MyBatis中默认的ObjectFactory是由org.apache.ibatis.reflection.factory.DefaultObjectFactory来提供的。在大部分的场景下我们都不用修改,如果要定制特定的工厂则需要进行配置。

例如我们自定义个ObjectFactory就需要在mybatis-config.xml配置如下内容:

    <objectFactory type="com.blog.custom.MyObjectFactory">
        <property name="userName" value="MyObjectFacotry"/>
    </objectFactory>

 

6.插件

插件是比较复杂的,使用时要特别小心。使用插件将覆盖一些MyBatis内部核心对象的行为,在没有了解MyBatiss内部运行原理之前我们没有必要去讨论它,后面会说的。

 

7.environment配置环境

配置环境可以注册多个数据源,每个数据源分为两大部分,一个是数据库源的配置,另一个是数据库事务的配置。

数据源配置如下:

 <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
      
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/blog_test"/>
        <property name="username" value="root"/>
        <property name="password" value="1234"/>
      </dataSource>
    </environment>
  </environments>

分析下上述配置:

(1)environments中的属性default,标明在缺省的情况下,我们将启动哪个数据源配置;

(2)environment元素是配置一个数据源的开始,属性id是设置这个数据源的标志,以便MyBatis上下文使用它;

(3)transactionManager配置的数据库事务,其中type属性有三种配置方式:

a.JDBC,采用JDBC方式管理事务,在独立编码中我们常常使用;

b.MANAGED,采用容器方式管理事务,在JNDI数据源中常用;

c.自定义,由使用者自定义数据库事务管理办法,适用于特殊应用。

(4)property元素则是可以配置数据源的各类属性,假如在此配置autoCommit=false,则是要求数据源不自动提交,默认情况是自动提交;

(5)dataSource标签,是配置数据源连接的信息,type属性是提供我们对数据库连接方式的配置,同样MyBatis提供了这么几种配置方式:

a.UNPOOLED,非连接池数据库;

b.POOLED,连接池数据库;

c.JNDI,JNDI数据源;

d.自定义数据源;

其中,配置的property元素,就是定义数据库的各类参数。

关于数据库事务MyBatis,它是由SqlSession去控制的,我们通过SqlSession提交或者回滚。我们插入一个角色对象,如果成功就提交,否则就回滚。不过大部分情况都是由Spring框架去控制。后面会讲到。

 

MyBatis内部为我们提供三种数据源的实现方式:

(1)UNPOOLED,非连接池,使用MyBatis提供的org.apache.ibatis.datasource.unpooled.UnpooledDataSource实现;

(2)POOLED,连接池,使用MyBatis提供的org.apache.ibatis.datasource.pooled.PooledDataSource实现;

(3)JNDI,使用MyBatis提供的org.apache.ibatis.datasource.jndi.JndiDataSourceFactory来获取数据源;

我们只需把数据源的属性type定义为UNPOOLED、POOLED、JNDI即可。

 

9.databaseIdProvider 数据库厂商标识

在相同数据库厂商的环境下,数据库厂商标识没有什么意义,在实际的应用中使用得比较少,因为使用不同厂商数据库的系统还是比较少的。MyBatis可能会运行在不同厂商的数据库中,它为此提供一个数据库标识,并提供自定义,它的作用在于指定SQL到对应的数据库厂商提供的数据库中运行。

这个不是特别重要,在此不详说,告诉读者有个这玩意。

 

主要参考《深入浅出MyBatis原理和实战》

posted @ 2018-11-18 16:32  挑战者V  阅读(366)  评论(3编辑  收藏  举报