MyBatis的XML配置

MyBatis配置文档结构如下:
在这里插入图片描述
1.properties
属性都是可外部配置且可动态替换的,既可以在Java属性文件中配置,也可以通过properties 元素的子元素配置,eg:

<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="dev_user"/>
  <property name="password" value="F2Fa3!33TYyg"/>
</properties>

然后其中的属性可以在整个配置文件中用来替换需要动态配置的属性值。eg:

<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 文件中对应的值来替换。属性也可以被传递到SqlSessionFactoryBuilder.build()方法中,如果属性在不止一个地方进行了配置,那么MyBatis按照下面的顺序加载:
1.在properties元素体内指定的属性首先被读取
2.然后根据properties元素中的resource属性读取类路径下属性文件或根据url属性指定的路径读取属性文件,并覆盖已读取的同名属性
3.最后读取作为方法参数传递的属性,并覆盖已读取的同名属性
因此,通过方法参数传递的属性具有最高优先级,resource/url属性中指定的配置文件次之,最低优先级的是properties属性中指定的属性

从MyBatis3.4.2开始,可以为占位符指定默认值,需要如下配置:
1.启用特性:

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

2.为占位符指定默认值:

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

settings解读:

<settings>
  <!--全局开启或关闭配置文件中的所有映射器已经配置的任何缓存-->
  <setting name="cacheEnabled" value="true"/>
  <!--延迟加载,开启时,所有关联对象延迟加载,可通过设置fetchType属性来覆盖该开关-->
  <setting name="lazyLoadingEnabled" value="true"/>
  <!--是否允许单一语句返回多结果(需要驱动支持)-->
  <setting name="multipleResultSetsEnabled" value="true"/>
  <!--使用列标签代表列名,不同驱动表现不同-->
  <setting name="useColumnLabel" value="true"/>
  <!--允许JDBC支持自动生成主键,需要驱动支持。如果设置为true则这个设置强制使用自动生成主键,尽管一些驱动不支持但仍可正常工作-->
  <setting name="useGeneratedKeys" value="false"/>
  <!--指定MyBatis应如何自动映射列到字段或属性,NONE表示取消自动映射,PARtIAL智慧映射没有定义嵌套结果集映射的结果集,FULL会自动映射任意复杂的结果集-->
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <!--指定发现自动映射目标未知列的行为-->
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <!--配置默认的执行器,SIMPLE就是普通的执行器,REUSE执行器会重用预处理语句;BATCH执行器将重用语句并执行批量更新-->
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <!--设置超时时间,它决定驱动等待数据库响应的秒数-->
  <setting name="defaultStatementTimeout" value="25"/>
  <!--为驱动的结果集获取数量设置一个提示值,此参数只可以在查询设置中被覆盖-->
  <setting name="defaultFetchSize" value="100"/>
  <!--允许在嵌套语句中使用分页,如果允许使用则设置为false-->
  <setting name="safeRowBoundsEnabled" value="false"/>
  <!-- 是否开启自动驼峰命名规则映射,即从经典数据库列明到经典Java属性名的类似映射-->
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <!--MyBatis利用本地缓存机制防止循环引用和加速重复嵌套查询,默认值为SESSIOn,这种情况下会缓存一个会话中执行的所有查询,若设置为STATEMENT,本地会话仅用在语句执行上,对相同SqlSession的不同调用将不会共享数据-->
  <setting name="localCacheScope" value="SESSION"/>
  <!-- 指定列的JDBC类型-->
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <!--指定哪个对象的方法触发一次延迟加载 -->
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

typeAliases:
类型别名是位Java类型设置一个短名字,它只和XML配置有关,可减少类完全限定名的冗余,eg:

<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会在包名下面搜索需要的JavaBean,比如:

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

每一个在包domain.blog中的Java Bean, 在没有注解的情况下,会使用Bean的首字母小写的非限定类名作为别名,若有注解,别名为其注解值。

typeHandlers:
无论是MyBatis在预处理语句中设置一个参数,还是从结果集中取出一个值,都会用类型处理器将获取的值以合适的方式转换成Java类型。其对应关系如图所示:
在这里插入图片描述
objectFactory:
MyBatis每次创建结果对象的新实例时,它都会使用一个对象工厂(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);
  }
  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允许在映射语句执行过程中的某一点进行拦截调用,默认情况下,MyBatis允许使用插件拦截的方法调用,示例如下:

// ExamplePlugin.java
@Intercepts({@Signature(
  type= Executor.class,
  method = "update",
  args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
  public Object intercept(Invocation invocation) throws Throwable {
    return invocation.proceed();
  }
  public Object plugin(Object target) {
    return Plugin.wrap(target, this);
  }
  public void setProperties(Properties properties) {
  }
}
<!-- mybatis-config.xml -->
<plugins>
  <plugin interceptor="org.mybatis.example.ExamplePlugin">
    <property name="someProperty" value="100"/>
  </plugin>
</plugins>

上面的插件将会拦截在Executor实例中的所有“update”方法调用
注意:除了用插件修改MyBatis核心行为外,还可以通过完全覆盖配置类来达到目的。只需继承后覆盖其中的每个方法,再把它传递到SqlSessionFactoryBuilder.buil(myConfig)方法即可,但这可能会严重影响MyBatis行为,所以一般不用

environments:
MyBatis可以配置成适应多种环境,这种机制有助于将SQL映射应用于多种数据库之中,显示情况下有多种理由需要这么做。例如:开发、测试和生产环境需要有不同的配置,或者想在具有相同Schema的多个生产数据库中使用相同的SQL映射。
注意:虽然可以配置多个环境,但每个SqlSessionFactory实例只能选择一种环境,所以,如果想连接两个数据库,就需要创建两个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>

关键点:
1.默认使用的环境id
2.每个environment元素定义的环境id
3.事务管理器的配置
4.数据源的配置

transactionManager:
在MyBatis中有两种类型的事物管理器(type=”[JDBC|MANAGED]”):
1.JDBC:这个配置直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域
2.MANAGED :这个配置几乎没做什么,它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期,默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将closeConnection 属性设置为 false 来阻止它默认的关闭行为:

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

如果使用Spring+MyBatis,则没有必要配置事务管理器,因为Spring模块自带的管理器会覆盖前面的配置

dataSource:
dataSource元素使用标准的JDBC数据源接口来配置JDBC连接对象的资源,为了使用延迟加载,数据源是必须配置的,有三种内建的数据源类型(type=”[UNPOOLED|POOLED|JNDI]”):
一、UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接,速度慢,UNPOOLED 类型的数据源仅仅需要配置以下5个属性:
1.driver:JDBC驱动的Java类的完全限定名
2.url:数据库的JDBC URL地址
3.username:的呢轮毂数据库的用户名
4.password:登录数据库的密码
5.defaultTransactionIsolationLevel:默认的连接事务隔离级别
二、POOLED:这个数据源的实现利用"池"的概念将JDBC连接对象组织起来,避免了创建新的连接实例时所必须的初始化和认证时间,通常在并发web应用快速响应请求处理中使用这种方式:
1.poolMaximumActiveConnections:在任意时间可以存在的活动连接数量,默认值为10
2.poolMaximumIdleConnections:任意时间可能存在的空闲连接数
3.poolMaximumCheckoutTime:在被强制返回之前,池中连接被检出的时间,默认值为20秒
4.poolTimeToWait:如果获取连接花费了相当长的时间,连接池会打印状态日志并重新尝试获取一个连接,默认值为20秒
5.poolMaximumLocalBadConnectionTolerance:这是一个关于坏连接容忍度的底层设置,作用于每一个尝试从缓存池获取连接的线程,如果这个线程获取到一个坏连接,那么这个数据源允许这个线程尝试重新获取一个新的连接,尝试次数不应该超过poolMaximumIdleConnections 与 poolMaximumLocalBadConnectionTolerance 之和,默认值为3
6.poolPingQuery – 发送到数据库的侦测查询,用来检验连接是否正常工作并准备接受请求。默认是“NO PING QUERY SET”,这会导致多数数据库驱动失败时带有一个恰当的错误消息。
poolPingEnabled – 是否启用侦测查询。若开启,需要设置 7.poolPingQuery 属性为一个可执行的 SQL 语句(最好是一个速度非常快的 SQL 语句),默认值:false。
8.poolPingConnectionsNotUsedFor – 配置 poolPingQuery 的频率。可以被设置为和数据库连接超时时间一样,来避免不必要的侦测,默认值:0(即所有连接每一时刻都被侦测 — 当然仅当 poolPingEnabled 为 true 时适用)。
三、JNDI:这个数据源的实现是为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文,其配置只需要两个属性:
1.initial_context:这个属性用来在InitialContext 中寻找上下文,是个可选属性,如果忽略,那么将会直接从InitialContext中寻找data_source属性
2.data_source:这是引用数据源实例位置的上下文路径,提供了initial_context配置时会在其返回的上下文中进行查找,没有提供时直接在InitialContext中查找。

使用第三方数据源的两种方法:
第一种,实现下面的接口:

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

第二种,继承下面父类:

import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0DataSourceFactory extends UnpooledDataSourceFactory {

  public C3P0DataSourceFactory() {
    this.dataSource = new ComboPooledDataSource();
  }
}

所需配置属性:

<dataSource type="org.myproject.C3P0DataSourceFactory">
  <property name="driver" value="org.postgresql.Driver"/>
  <property name="url" value="jdbc:postgresql:mydb"/>
  <property name="username" value="postgres"/>
  <property name="password" value="root"/>
</dataSource>

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

<databaseIdProvider type="DB_VENDOR" />

mappers:
配置以上行为后,就可以配置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>

猜你喜欢

转载自blog.csdn.net/weixin_43638314/article/details/93311490