Mybatis配置

Mybatis配置文件并不复杂,它的所有元素如下:

<?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/><!-- 属性 -->
    <settings/><!-- 设置 -->
    <typeAliases/><!-- 类型别名 -->
    <typeHandlers/><!-- 类型处理器 -->
    <objectFactory/><!-- 对象工厂 -->
    <plugins/><!-- 插件 -->
    <environments><!-- 配置环境 -->
        <environment><!-- 环境变量 -->
            <transactionManager/><!-- 事务管理器 -->
            <dataSource/><!-- 数据源 -->
        </environment>
    </environments>
    <databaseIdProvider/><!-- 数据库厂商标识 -->
    <mappers/><!-- 映射器 -->
</configuration>

需要注意的是,顺序不能颠倒,否则启动会发生异常.

1、properties属性

properties属性可以给系统配置一些运行参数,可以放在xml文件或properties文件中。mybatis提供了三种方式让我们使用properties:
property元素;
properties文件;
程序代码传递;

1.1 property元素:
<?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>
        <property name="db.driver" value="com.mysql.jdbc.Driver"/>
        <property name="db.url" value="jdbc:mysql://localhost:3306/ssm"/>
        <property name="db.username" value="root"/>
        <property name="db.password" value="llll"/>
    </properties>

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

</configuration>

这样就可以一次定义到处使用了

1.2 使用properties文件

这个是比较普遍的大家常用的方法。一来这个文件十分简单,里面就是存的键值对,二来可以吧多个键值对放在不同文件,以便于日后维护。
jdbc.properties如下:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.username=root
jdbc.password=qq11qq

在Mybatis中通过properties的属性resource来引入properties文件

<properties resource="jdbc.properties" />
1.3 使用程序传递方式传递参数

在真实的生产环境中,数据库密码需要保密。故一般都需要将用户名密码经过加密成为密文后,配置到properties文件中。假设提供了Utils.decode(cipferText)进行解密。那么创建SqlSessionFactory代码清单如下所示:

String resource = "mybatis-config.xml";
InputStream inputStream;
InputStream in = Resources.getResourceAsStream(resource);
Properties props = new Properties();
props.load(in);
String username = props.getProperty("jdbc.username");
String password = props.getProperty("jdbc.password");
props.put("jdbc.username",Utils.decode(username));
props.put("jdbc.password",Utils.decode(password));
inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,props);

2、settings设置

settings是mybatis中最复杂的配置,它能深刻的影响mybatis底层的运行,但是在大部分情况下,使用默认值便可以运行。下面是全量的配置案例:

    <settings>
        <setting name="cacheEnabled" value="true"/>
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="multipleResultSetsEnabled" value="true"/>
        <setting name="useColumnLable" value="true"/>
        <setting name="useGeneratedKeys" value="false"/>
        <setting name="autoMappingBehavior" value="PARTIAL"/>
        <setting name="autoMappingUnknowColumnBehavior" value="WARNNING"/>
        <setting name="defaultExecutorType" value="SIMPLE"/>
        <setting name="defaultStatementTimeout" value="25"/>
        <setting name="defaultFetchSize" value="100"/>
        <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"/>
    </settings>

常见的几个设置的用法简介:

配置项 作用 配置选项说明 默认值
cacheEnabled 该配置影响所有映射器中配置缓存的全局开关 true/false true
lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。在特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态 true/false false
aggressiveLazyLoading 当启用时,对任意延迟属性的调用会使得带有延迟加载属性的对象完整加载;反之,每种属性将会按需加载 true/false 版本3.1.4(不包含)之前true,之后false
autoMappingBehavior 指定mybatis应如何映射列到字段或属性。NONE表示取消自动映射;PARTIAL表示只会自动映射,没有定义嵌套结果集和映射结果集;FULL会自动映射任意的复杂结果集(无论是否嵌套) NONE/PARTIAL/FULL PARTIAL
defaultExecutorType 配置默认的执行器 。SIMPLE是普通的执行器;Reuse会重用预处理语句(Prepared statements);BATCH执行器将重用语句并执行批量更新 SIMPLE/REUSE/BATCH SIMPLE
mapUnderscoreToCamelCase 是否开启自动驼峰命名规则映射,即从经典数据库列名A_COLUMN到经典java属性名aColumn的类似映射 true/false false

3、typeAliases 别名

由于类的全限定名很长,在多次需要使用的时候,比较不方便,在mybatis中允许定义一个简写来代替,这就是别名,分为系统定义和自定义别名。在mybatis中别名由类TypeAliasRegistry来定义(org.apache.ibatis.type.TypeAliasRegistry)。在mybatis中,别名不区分大小写。
3.1、自定义别名
由于现实开发中,存在许多自定义的对象需要重复使用,因此mybatis中也提供了用户自定义别名的规则。我们可以通过TypeAliasRegistry类的registerAlias方法注册,也可以采用配置文件或或者扫描方式来定义它。
3.1.1、使用配置文件定义

    <typeAliases>
        <typeAlias type="com.ssm.pojo.Role" alias="role"/>
        <typeAlias type="com.ssm.pojo.User" alias="user"/>
    </typeAliases>

3.1.2、扫描
现实开发中可能存在大量的实体类,如果一个一个的配置就不适合了。因此mybatis还提供了扫描别名。如上配置:两个实体类位于同一包下,还可以这样配置:

    <typeAliases>
        <package name="com.ssm.pojo"/>
    </typeAliases>

3.1.3、注解配置别名
如果多个类同时包含User实体类,在通过包扫描后,可能会有冲突。则可以通过注解来区分。比如:

package com.ssm.pojo;
@Alias("user3")
public Class User{
  ... ...
}

这样就可以避免因为别名重名导致的扫描失败的问题。

4、typeHandler类型转换器
在JDBC中,需要在PreparedStatement对象中设置哪些已经预编译过的SQL语句的参数。执行SQL后,会通过ResultSet对象获取得到数据库的数据。而这些,Mybatis是根据数据库数据的类型通过TypeHandler来实现的。
在myBatis中,TypeHandler都需要实现接口org.apache.ibatis.type.TypeHandler ,源码如下:

public interface TypeHandler <T> {
    void setParameter(java.sql.PreparedStatement preparedStatement, int i, T t, org.apache.ibatis.type.JdbcType jdbcType) throws java.sql.SQLException;

    T getResult(java.sql.ResultSet resultSet, java.lang.String s) throws java.sql.SQLException;

    T getResult(java.sql.ResultSet resultSet, int i) throws java.sql.SQLException;

    T getResult(java.sql.CallableStatement callableStatement, int i) throws java.sql.SQLException;
}

其中setParameter方法是使用TypeHandler通过PreparedStatement对象进行设置SQL参数的时候使用的具体方法,其中i是参数在SQL的下标,parameter是参数,jdbcType是数据库类型。
如果研究TypeHandler的源码,会发现其都实现了org.apache.ibatis.type.BaseTypeHandler,所以我们先看一下BaseTypeHandler的源码:

/**
 *    Copyright 2009-2019 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.type;

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

import org.apache.ibatis.executor.result.ResultMapException;
import org.apache.ibatis.session.Configuration;

/**
 * The base {@link TypeHandler} for references a generic type.
 * <p>
 * Important: Since 3.5.0, This class never call the {@link ResultSet#wasNull()} and
 * {@link CallableStatement#wasNull()} method for handling the SQL {@code NULL} value.
 * In other words, {@code null} value handling should be performed on subclass.
 * </p>
 *
 * @author Clinton Begin
 * @author Simone Tripodi
 * @author Kzuki Shimizu
 */
public abstract class BaseTypeHandler<T> extends TypeReference<T> implements TypeHandler<T> {

  /**
   * @deprecated Since 3.5.0 - See https://github.com/mybatis/mybatis-3/issues/1203. This field will remove future.
   */
  @Deprecated
  protected Configuration configuration;

  /**
   * @deprecated Since 3.5.0 - See https://github.com/mybatis/mybatis-3/issues/1203. This property will remove future.
   */
  @Deprecated
  public void setConfiguration(Configuration c) {
    this.configuration = c;
  }

  @Override
  public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
    if (parameter == null) {
      if (jdbcType == null) {
        throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
      }
      try {
        ps.setNull(i, jdbcType.TYPE_CODE);
      } catch (SQLException e) {
        throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . "
              + "Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. "
              + "Cause: " + e, e);
      }
    } else {
      try {
        setNonNullParameter(ps, i, parameter, jdbcType);
      } catch (Exception e) {
        throw new TypeException("Error setting non null for parameter #" + i + " with JdbcType " + jdbcType + " . "
              + "Try setting a different JdbcType for this parameter or a different configuration property. "
              + "Cause: " + e, e);
      }
    }
  }

  @Override
  public T getResult(ResultSet rs, String columnName) throws SQLException {
    try {
      return getNullableResult(rs, columnName);
    } catch (Exception e) {
      throw new ResultMapException("Error attempting to get column '" + columnName + "' from result set.  Cause: " + e, e);
    }
  }

  @Override
  public T getResult(ResultSet rs, int columnIndex) throws SQLException {
    try {
      return getNullableResult(rs, columnIndex);
    } catch (Exception e) {
      throw new ResultMapException("Error attempting to get column #" + columnIndex + " from result set.  Cause: " + e, e);
    }
  }

  @Override
  public T getResult(CallableStatement cs, int columnIndex) throws SQLException {
    try {
      return getNullableResult(cs, columnIndex);
    } catch (Exception e) {
      throw new ResultMapException("Error attempting to get column #" + columnIndex + " from callable statement.  Cause: " + e, e);
    }
  }

  public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

  /**
   * @param columnName Colunm name, when configuration <code>useColumnLabel</code> is <code>false</code>
   */
  public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException;

  public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException;

  public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;

}

我们简单分析一下源码:
1、这是个抽象类,实现了TypeHandler接口的四个方法,定义了4个抽象方法,需要其子类去实现。下面将会以StringTypeHandler来简单说明一下。
2、getResult方法:非空结果集是通过getNullableResult来实现。
3、setParameter方法:如果parameter与jdbcType同时为null,抛出异常。
4、getNullableResult用于存储过程。

下面通过StringTypeHandler 来加深了解TypeHandler:

/**
 *    Copyright 2009-2015 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
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);
  }
}

在mybatis中采用org.apache.ibatis.type.TypeHandlerRegistry类对象的register来进行注册。其源码如下(已删减部分)

/**
 * @author Clinton Begin
 * @author Kazuki Shimizu
 */
public final class TypeHandlerRegistry {
  public TypeHandlerRegistry() {
    register(Boolean.class, new BooleanTypeHandler());
    register(boolean.class, new BooleanTypeHandler());
    ... ...
    register(Byte[].class, new ByteObjectArrayTypeHandler());
    register(Byte[].class, JdbcType.BLOB, new BlobByteObjectArrayTypeHandler());
   ... ...
  }
}

自定义的TypeHandler一般是通过配置或扫描:
根据系统定义的可以知道,要实现TypeHandler就需要去实现接口TypeHandler或者继承BaseTypeHandler(其也实现了接口TypeHandler)。这里我们仿造一个StringTypeHandler。代码如下:

package com.ssm.chapter3.typehandler;

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

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


/**
 * Created by czz on 2019/8/4.
 */
public class MyTypeHandler implements TypeHandler<String> {
    Logger log = Logger.getLogger(MyTypeHandler.class);

    @Override
    public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
            throws SQLException{
        log.info("String参数为: 【"+parameter+"】");
        ps.setString(i,parameter);
    }

    @Override
    public String getResult(ResultSet rs, String columnName) throws SQLException{
        String result = rs.getString(columnName);
        log.info("读取String参数-01 : 【"+result+"】");
        return result;
    }

    @Override
    public String getResult(ResultSet rs, int columnIndex) throws SQLException{
        String result = rs.getString(columnIndex);
        log.info("读取String参数-02 : 【"+result+"】");
        return result;
    }

    @Override
    public String getResult(CallableStatement cs, int columnIndex) throws SQLException{
        String result = cs.getString(columnIndex);
        log.info("读取String参数-03 : 【"+result+"】");
        return result;
    }
}


定义完成之后,还需要额皮质完成系统才会读取它,注册它。

    <typeHandlers>
        <typeHandler handler="com.ssm.chapter3.typehandler.MyTypeHandler" jdbcType="VARCHAR" javaType="string"/>
    </typeHandlers>

还可以显示启用TypeHandler,代码如下:

	<resultMap id="roleMapper" type="role">
		<result property="id" column="id"></result>
		<result property="roleName" column="role_name" jdbcType="VARCHAR" javaType="string"/>
		<result property="note" column="note" typeHandler="com.ssm.chapter3.typehandler.MyTypeHandler"/>
	</resultMap>


	<select id="findRoles" parameterType="long" resultType="com.ssm.pojo.Role">
		SELECT id ,role_name roleName,note FROM t_role WHERE role_name LIKE concat('%',#{roleName,jdbcType=VARCHAR,javaType=string},'%')
	</select>


	<select id="findRoles" parameterType="long" resultType="com.ssm.pojo.Role">
		SELECT id ,role_name roleName,note FROM t_role WHERE role_name LIKE concat('%',#{roleName,typeHandler=com.ssm.chapter3.typehandler.MyTypeHandler},'%')
	</select>

由于有时候自定义的类型会比较多,可以考虑使用包扫描的形式。但是这样就无法指定JavaType和jdbcType了,此时可以用注解处理。代码如下:

    <typeHandlers>
        <package name="com.ssm.chapter3.typehandler"/>
    </typeHandlers>
@MappedTypes(String.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class MyTypeHandler implements TypeHandler<String> {
   ... ...
}

5、ObjectFactory(对象工厂)

当创建结果集时,Mybatis会使用一个对象工厂来创建这个结果集实例。在默认的情况下,Mybatis会使用其自定义的对象工厂------DefaultObjectFactory(org.apache.ibatis.reflection.DefaultObjectFactory),并给予配置。在大部分情况下,我们都不需要自定义返回规则,因为这些比较复杂且容易出错。更多的情况,可能是继承DefaultObjectFactory,通过一定的改写来完成我们所需要的工作。

6、插件

插件是mybatis中最强大和灵活的组件,同时也是最复杂最难以使用的的组件,而且因为它将覆盖mybatis底层对象的核心方法和属性,所以十分危险。

7、environments(运行环境)

在mybatis中,运行环境的主要作用是配置数据库信息,它可以配置多个数据库,一般而言只需要配置其中的一个就可以了。他下面又分为两个可配置的元素:事务管理器(TransactionManager)和数据源(DataSource)。运行环境配置,代码如下:

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

7.1、事务管理器(TransactionManager)
在mybatis中transactionManager提供了两个实现类,他们需要实现接口 org.apache.ibatis.transaction.Transaction接口定义如下:

/**
 *    Copyright 2009-2019 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.transaction;

import java.sql.Connection;
import java.sql.SQLException;

public interface Transaction {

  Connection getConnection() throws SQLException;

  void commit() throws SQLException;

  void rollback() throws SQLException;

  void close() throws SQLException;

  Integer getTimeout() throws SQLException;

}

根据接口的方法可知,它主要的工作就是提交(commit),回滚(rollback)和关闭(close)数据库的事务。mybatis为Transaction接口提供了两个实现类JdbcTransaction和ManagedTransaction,因此对应着两个工厂JdbcTransactionFactory和ManagedTransactionFactory。这两个工厂都需要实现TransactionFactory接口,通过他们会生成Transaction对象。于是,可以把事务管理器配置成一下两种方式:

<transactionManager type="JDBC"></transactionManager>
<transactionManager type="MANAED"></transactionManager>

transactionFactory源码如下:

public interface TransactionFactory {
  default void setProperties(Properties props) {
    // NOP
  }
  Transaction newTransaction(Connection conn);
  Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);

}

下面是JdbcTransactionFactory 的源码,通过源码可以更了解该工厂如何生产JdbcTransaction的。这部分源码相对来讲比较容易理解。

/**
 *    Copyright 2009-2019 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.transaction.jdbc;

import java.sql.Connection;
import javax.sql.DataSource;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.TransactionFactory;

public class JdbcTransactionFactory implements TransactionFactory {
  @Override
  public Transaction newTransaction(Connection conn) {
    return new JdbcTransaction(conn);
  }
  @Override
  public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
    return new JdbcTransaction(ds, level, autoCommit);
  }
}


当然如果不想采用mybatis给提供的规则,我们可以自定义事务工厂:

package com.ssm.chapter3.objectfactory;

import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.jdbc.JdbcTransaction;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * Created by czz on 2019/8/5.
 */
public class MyTransaction extends JdbcTransaction implements Transaction {
    public MyTransaction(DataSource dataSource, TransactionIsolationLevel level,boolean autoCommit){
        super(dataSource,level,autoCommit);
    }
    
    public MyTransaction(Connection conn){
        super(conn);
    }
    
    @Override
    public Connection getConnection() throws SQLException {
        return super.getConnection();
    }

    @Override
    public void rollback() throws SQLException{
        super.rollback();
    }
    
    @Override
    public void commit() throws SQLException{
        super.commit();
    }
    
    @Override
    public Integer getTimeout() throws SQLException{
        return super.getTimeout();
    }
    
}


package com.ssm.chapter3.objectfactory;

import org.apache.ibatis.session.TransactionIsolationLevel;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.TransactionFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.util.Properties;

/**
 * Created by czz on 2019/8/5.
 */
public class MyTransactionFactory implements TransactionFactory {
    @Override
    public void setProperties(Properties props){}

    @Override
    public Transaction newTransaction(Connection conn){
        return new MyTransaction(conn);
    }

    @Override
    public Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level,boolean autoCommit){
        return new MyTransaction(dataSource,level,autoCommit);
    }
}


配置自定义事务

<transactionManager> type="com.learn.ssm.chapter4.transaction,MyTransactionFactory"

7.2environment数据源环境
environment的主要作用是配置数据库,在mybatis中,数据库通过PooledDataSourceFactory、UnpooledDataSourceFactory、JndiDataSourceFactory三个工厂类来提供。前两者会产生PooledDataSource、UnpooledDataSource对象,而JndiDataSourceFactory则会jndi的信息拿到外部容器实现的数据库连接对象。无论如何,这三个工厂类生成的产品都是一个实现了DataSource接口的数据库连接对象。配置方法分别如下所示:
<dataSource type="UNPOOLED">
<dataSource type="POOLED">
<dataSource type="JNDI">

7.2.1 UNPOOLED
采用非数据库池的管理方式,每次请求都会打开一个新的数据库连接,所以创建会比较慢。在一些对性能要求没那么高的场合可以使用。可以配置以下属性:
driver:数据库驱动名;
url
username
password
DefaultTransactionIsolationLevel:默认的连接事务隔离级别。

7.2.2 Pooled
利用池的概念将JDBC的connection对象组织起来。它开始会有一些空置,以及一些连接好的数据库连接。所以在请求时,无需再建立和验证,省去了创建新的连接实例时所必需的初始化和认证时间。它还空置最大连接数,以免过多的连接导致系统瓶颈。
除了UNPOOLED的属性外,会有更多属性用来配置POOLED数据源:
poolMaximumActiveConnections:
poolMaximumIdleConnections:
poolMaximumCheckoutTime:
poolTimeToWait:
poolPingQuery:
poolPingEnabled:
poolPingConnectionsNotUserFor:

7.2.3 JNDI
可以自定义数据源工厂,并进行配置

<dataSource type="com.......DbcpDataSourceFactory">
  <property name="driver" value=""/>
... ...
</dataSource>

8、databaseIdProvider数据库厂商标识

主要用于给不同客户提供系统需要不同数据库连接时,配置如下:

    <databaseIdProvider type="DB_VENDOR">
        <property name="Oracle" value="oracle"/>
        <property name="MySql" value="mysql"/>
        <property name="DB2" value="db2"/>
    </databaseIdProvider>

标识SQL适用何种数据库:

	<select id="getRole" parameterType="long" resultType="role" databaseId="oracle">
		SELECT id,role_name as roleName ,note FROM t_role WHERE id = #{id}
	</select>
	<select id="getRole" parameterType="long" resultType="role" databaseId="mysql">
		SELECT id,role_name as roleName ,note FROM t_role WHERE 1=1 AND id = #{id}
	</select>

9、引入映射器的方法

    <!--文件路径引入 -->
    <mappers>
        <mapper resource="com/ssm/mapper"/>
    </mappers>

    <!--包名引入 -->
    <mappers>
        <package name="com.ssm.mapper"/>
    </mappers>

    <!--类注册引入 -->
    <mappers>
        <mapper class="com.ssm.mapper.RoleMapper"/>
        <mapper class="com.ssm.mapper.UserMapper"/>
    </mappers>

    <!--使用UserMapper.xml引入 -->
    <mappers>
        <mapper url="file:///var/mappers/com/ssm/mapper/UserMapper.xml"/>
        <mapper url="file:///var/mappers/com/ssm/mapper/RoleMapper.xml"/>
    </mappers>

大家有兴趣也可以关注我的公众号查看文章。

posted @ 2019-09-30 10:53  东方欲晓_莫道君行早  阅读(376)  评论(0编辑  收藏  举报