MyBatis系列三 配置(下)

五、ObjectFactory

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

  我们这里配置了一个对象工厂MyObjectFactory,对它的要求是实现ObjectFactory的接 口。实际上DefaultObjectFactory已经实现了 ObjectFactory的接口,我们可以通过继承 DefaultObjectFactory来简化编程。下面给出它的实现代码和测试结果,如代码清单3-26所示。

 

 

  这里并没有实现额外的功能,只是做一下测试而已,如果定制需要自己编写里面的逻 辑。让我们运行一下,查看其运行的结果。

 

 

 

  从运行的结果可以看出,首先,setProperties方法可以使得我们如何去处理设置进去的 属性,而create方法分别可以处理单个对象和列表对象。其次,我们配置的ObjectFactory 已经生效。注意,大部分的情况下,我们不需要使用自己配置的ObjectFactory,使用系统 默认的即可。

六、插件

  插件(plugins)是比较复杂的,使用时要特别小心。使用插件将覆盖一些MyBatis 部核心对象的行为,在没有了解MyBatis内部运行原理之前我们没有必要去讨论它,所以这里暂时不讨论。

七、environments 配置环境

1、概述

 

  配置环境可以注册多个数据源(dataSource),每一个数据源分为两大部分:一个是数据库源的配置,另外一个是数据库事务(transactionManager)的配置。我们来看一个连接 池的数据源的配置,如代码清单3.27所示。

我们分析一下上面的配置。

  • environments中的属性default,标明在缺省的情况下,我们将启用哪个数据源配置。
  • environment元素是配置一个数据源的开始,属性id是设置这个数据源的标志,以便MyBatis上下文使用它。
  • transactionManager配置的是数据库事务,其中type属性有3种配置方式。
  1. JDBC,釆用JDBC方式管理事务,在独立编码中我们常常使用。
  2.  MANAGED,釆用容器方式管理事务,在JNDI数据源中常用。
  3. 自定义,由使用者自定义数据库事务管理办法,适用于特殊应用。
  • property元素则是可以配置数据源的各类属性,我们这里配置了 autoCommit = false,则是要求数据源不自动提交。
  • dataSource标签,是配置数据源连接的信息,type属性是提供我们对数据库连接方 式的配置,同样MyBatis提供这么几种配置方式:
  1. UNPOOLED,非连接池数据库(U叩ooledDataSource)o
  2. POOLED,连接池数据库(PooledDataSource)。
  3. JNDI, JNDI 数据源(JNDIDataSource)。
  4. 自定义数据源。

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

2、数据库事务

  数据库事务MyBatis是交由SqlSession去控制的,我们可以通过SqlSession提交 (commit)或者回滚(rollback)o我们插入一个角色对象,如果成功就提交,否则就回滚, 如代码清单3-28所示。

 

 

代码清单3-28:数据库事务处理

try (
    sqlSession = SqlSessionFactoryUtil.openSqlSession();
   RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
   int count = roleMapper.insertRole(role);    sqlSession.commit();    return count; }catch(Exception ex) (   sqlSession.rollback(); }finally (   sqlSession.close(); }

在大部分的工作环境下,我们都会使用Spring框架来控制它,这些内容将放到第8 去讨论。

3、数据源

MyBatis内部为我们提供了 3种数据源的实现方式。

  • UNPOOLED,非连接池,使用 MyBatis 提供的 org.apache.ibatis.datasource.u叩ooled. UnpooledDataSource 实现。
  • POOLED,连接池,使用 MyBatis 提供的 o rg.apache.ibatis.datasource.pooled.PooledData Source 实现。
  • JNDI,使用 MyBatis 提供的 org.apache.ibatis.datasource.jndi.JndiDataSourceFactory 来获取数据源。

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

这3种实现方式比较简单,只需要配置参数即可,但有时候我们需要使用其他的数据源。 如果使用自定义数据源,它必须实现org.apache.ibatis.datasource.DataSourceFactory接口。比 如说我们可能要用DBCP数据源,这个时候我们需要自定义数据源,如代码清单3-29所示。

 

 

 

使用DBCP数据源需要我们提供一个类去配置它。我们按照下面的方法配置就可以使 DBCP数据源了。

 

 

 八、databaseldProvider数据库厂商标识

 

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

1、使用系统默认规则

  MyBatis提供默认的配置规则,如代码清单3-30所示。

 

 

   type="DB_VENDOR"是启动MyBatis内部注册的策略器。首先MyBatis会将你的配置读入Configuration类里面,在连接数据库后调用getDatabaseProductName()方法去获取数据库的信息,然后用我们配置的name值去做匹配来得到Databaseldo我们把这些配置到我们的例 子里,而我们的例子使用的正是MySQL数据库。这个时候,我们可以用下面的代码来获 得数据库的ID,显然结果就是MySQL。

  我们也可以指定SQL在哪个数据库厂商执行,我们把Mapper的XML配置修改一下, 如代码清单3.31所示。

  

在多了一个databaseld属性的情况下,MyBatis将提供如下规则。

  • 如果没有配置databaseldProvider标签,那么databaseld就会返回nulL
  • 如果配置了 databaseldProvider标签,MyBatis就会用配置的name值去匹配数据库 信息,如果匹配得上就会设置databaseld,否则依旧为null。
  • 如果Configuration的databaseld不为空,则它只会找到配置databaseld的SQL 语句。
  • MyBatis会加载不带databaseld属性和带有匹配当前数据库databaseld属性的所有语 句。如果同时找到带有databaseld和不带databaseld的相同语句,则后者会被舍弃。

2、不使用系统默认规则

  MyBatis也提供规则允许自定义,我们只要实现databaseldProvider接口,并且实现配 置即可,下面我们来看一个实例。

  首先,写好我们自定义的规则类,如代码清单3.32所示。

代码清单 3-32: MydatabaseldProvider.java

package com.learn.chapters.databaseIdprovider; import java.sql.SQLException;
import java.util.Properties;
import javax.sql•DataSource;
import org.apache•ibatis.mapping.DatabaseIdProvider;
public class MydatabaseIdProvider implements DatabaseIdProvider{
  private Properties properties = null;
  @Override
  public void setProperties(Properties properties) (
    this.properties = properties;
  }
  @Override
  public String getDatabaseld(DataSource ds) throws SQLException {
    String dbName = ds.getConnection().getMetaData().getDatabaseProductName(); String dbld = (String)this.properties.get(dbName);
    return dbld;
  }
}

其次,注册这个类到MyBatis上下文环境中,我们这样配置databaseldProvider标签, 如代码清单3-33所示。

代码清单 3-33:配置 databaseldProvider

<databaseIdProvider
type="com.learn.chapter3.databaseIdprovider.MydatabaseIdProvider">
<property name="SQL Server" value="sqlserver"/>
<property name="MySQL" value="mysql"/ >
<property name="DB2" value="db2”/ >
<property name="Oracle" value="oracle" />
</databaseIdProvider>

  我们把type修改为我们自己实现的类,类里面setProperties方法的参数传递进去的将 会是我们在XML里面配置的信息,我们保存在类的变量properties里,方便以后读出。在 方法getDatabaseld中,传递的参数是数据库数据源,我们获取其名称,然后通过properties 的键值找到对应的databaseld。

  如有特殊的要求,我们可以根据自己所需要的规则来编写databaseldProvider0配置 Mapper、使用规则和默认规则是一致的。

九、引入映射器的方法

  映射器是MyBatis最复杂、最核心的组件。本节着重讨论如何引入映射器。而它的参 数类型、动态SQL、定义SQL、缓存信息等功能我们会在后面的几章专门讨论。

  第2章讲解了映射器定义命名空间的方法,命名空间对应的是一个接口的全路径,而不是实现类,我们之后会讨论系统是如何现实的,现在我们只要知道使用这个接口能调度我们想要的SQL,并组装成为我们想要的结果即可。

  首先,定义映射器的接口,如代码清单3.34所示。

代码清单3-34:定义Mapper接口

package com.learn.chapter3.mapper;
import java.util.List;
import com.learn.chapter3.po.Role;
public interface RoleMapper {
  public Role getRole(Long id);
}

其次,给出XML文件,如代码清单3.35所示。

引入映射器的方法很多,一般分为以下几种。

我们可以根据实际需要选择恰当的引入方法。

 

 

 

 

 

 

 

 

 

posted @ 2020-09-03 20:38  跃小云  阅读(96)  评论(0编辑  收藏  举报