关于mybatis-config.xml文件的基础解释

今天是我第一天落户博客园,想想从mybatis框架开始写起吧。mybatis框架与Hibernate框架相比来讲,专一于SQL语句,对SQL语句的要求比较高吧。java

我以为,对于mybatis框架来讲,最要紧的就是两个配置文件,mybatis-config.xml和XxxxMapper.xml文件了,因此就从mybatis-config.xml开始提及吧。web

首先呢是mybatis-config.xml文件的头部:sql

<?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"> 

能够看出这个xml文件引用了一个DTD文件的约束,因此说对框架来讲是个有效的xml文件,这个两个文件均可以在官网上下载,mybatis框架也是个开源的框架,这一点是很好的数据库

注意:!!!这个xml文件因为dtd的约束使得标签的顺序惟一,标签若是出现就必须按照严格的顺序书写(IDE是能够联网关联的,也能够本身设置)apache

咱们来看这个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>
</configuration> 

configuration这个标签中就是须要给框架配置的一系列标签。服务器

首先是properties标签:mybatis

属性配置元素properties能够将配置值写死到mybatis-config.xml中,也能够具体到一个属性文件中,而且使用属性文件的key名做为占位符,在下述的配置中,咱们将数据库链接属性配置到了application.properties文件中,而且为driver,URL等属性使用了占位符。oracle

在applications.properties文件中配置数据库链接参数,以下所示:
jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:XE
jdbc.username=xxx 
jdbc.password=xxxapp

<properties resource="application.properties"> 
    <!-- 这是设置优先级比较低的默认属性 -->
    <property name="username" value="db_user" /> 
    <property name="password" value="verysecurepwd" /> 
</properties> 

这样咱们就能够在environment标签中调用上述配置文件中的K-V值了:

envionment标签是环境相关设置标签,使用以下:

<!-- 这里的环境能够有多个,环境id不一样,做用不一样,以下,第一个environment做用是开发,第一个environment做用是生产 -->
  <environments default="development"> 
     <!-- 这里的id是指环境的id,经常写为本身的做用 -->
    <environment id="development"> 
    <!-- 这个属性是链接管理类型 通常有2个值可选-->
      <!-- JDBC 是须要应用程序本身管理事务 -->
      <!-- 例如,部署到ApacheTomcat的应用程序,须要应用程序本身管理事务。由于ApacheTomcat不会帮咱们管理事务。 -->
      <!-- MANAGED 是让服务器自动管理事务 像glassfish 服务器-->
      <transactionManager type="JDBC" /> 
      <!-- dataSource的类型type属性能够配置成其内置类型之一,如UNPOOLED,POOLED,JNDI。 -->
      <dataSource type="POOLED"> 
<property name="driver" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> <environment id="production"> <transactionManager type="MANAGED" /> <dataSource type="JNDI"> <property name="data_source" value="java:comp/jdbc/MyBatisDemoDS" /> </dataSource> </environment> </environments>

typeAliases标签:这个标签是起个别名的做用

<!-- 这个属性就是对pojo类起个别名 -->
<typeAliases> 
    <!-- 这里的意思是将 pojo.Student 类别名为 Student-->
    <typeAlias alias="Student" type="pojo.Student" /> 
    <!-- 这里的意思是将 pojo包下的全部类进行别名,好比pojo.Student 就会别名为student-->
    <!-- 优先级不高-->
    <package name="pojo" /> 
</typeAliases> 

接下来是一个比较复杂的问题:

类型处理器,这是一个在mybatis中相对复杂的问题,分为两种状况,一是内建的类型处理器,再者是本身定义的类型

MyBatis对于如下的类型使用内建的类型处理器
全部的基本数据类型、基本类型的包裹类型
byte[]、java.util.Date、java.sql.Date、java,sql.Time、java.sql.Timestamp、java枚举类型等

若是是本身定义的类型,例子以下
假如在XxxxMapper.xml文件中配置一个insert插入语句,这里的phone是Student的一个内置对象,类型为PhoneNumber:

<insert id="insertStudent" parameter Type="Student"> insert into students(name,email,phone) values(#{name},#{email},#{phone}) </insert> 

为了让MyBatis明白怎样处理这个自定义的Java对象类型,如PhoneNumber,咱们能够建立一个自定义的类型处理器,首先咱们须要处理PhoneNumber类,加入一个getAsString方法

public class PhoneNumber{ private String countryCode; private String stateCode; private String number; public PhoneNumber(){} public PhoneNumber(String countryCode, String stateCode, String number){ this.countryCode = countryCode; this.stateCode = stateCode; this.number = number; } public PhoneNumber(String str){ if(str!=null){ String[] args = str.split("-"); this.countryCode = args[0]; this.stateCode = args[1]; this.number = args[2]; } } public String getAsString() { return countryCode + "-" + stateCode + "-" + number; } // Setters and getters 
}            

MyBatis提供了抽象类BaseTypeHandler<T> ,咱们能够继承此类建立自定义类型处理器。

public class PhoneTypeHandler extends BaseTypeHandler<PhoneNumber>{ //遇到PhoneNumber参数的时候应该如何在ps中设置值
 @Override public void setNonNullParameter(PreparedStatement ps, int i, PhoneNumber parameter, JdbcType jdbcType) throws SQLException { //这个方法就是调用了PhoneNumber类中的getAsString方法 //将这个对象以一个字符串的方式存入对应的表字段中
 ps.setString(i, parameter.getAsString()); } //查询中遇到PhoneNumber类型的应该如何封装(使用列名封装)
 @Override public PhoneNumber getNullableResult(ResultSet rs, String columnName) throws SQLException { //由上面的方法能够知道 //这个方法能够将以字符串的方式存入对应的表字段中的PhoneNumber对象取出来 //调用了PhoneNumber类中的一参构造器从新封装为对象
            return new PhoneNumber(rs.getString(columnName)); } //查询中遇到PhoneNumber类型的应该如何封装(使用列的下标)
 @Override public PhoneNumber getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return new PhoneNumber(rs.getString(columnIndex)); } //CallableStatement使用中遇到了PhoneNumber类型的应该如何封装
 @Override public PhoneNumber getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return new PhoneNumber(cs.getString(columnIndex)); } }

 

最后就须要在mybatis-config.xml文件中配置一下

  <typeHandlers> 
    <typeHandler handler="typehandlers.PhoneTypeHandler" /> 
    <!--这个标签貌似也是个别名的做用,不过我没用过-->
    <package name="typehandlers" /> 
  </typeHandlers> 

接下来是mappers元素,主要用于 SQL映射

SQLMapper文件中主要是对SQL语句的映射,代表这个sql语句对应哪一个方法的调用。咱们须要在mybatis-config.xml文件中配置 SQLMapper文件的位置。

resource属性用来指定在classpath中的mapper文件。
url属性用来经过彻底文件系统路径或者web URL地址来指向mapper文件
class属性用来指向一个mapper接口
package属性用来指向能够找到Mapper接口的包名 

其实在项目中经常只要一个属性就足够定位了

  <mappers> 
    <mapper resource="mappers/StudentMapper.xml" /> 
    <mapper url="file:///D:/mybatisdemo/app/mappers/StudentMapper.xml" /> 
    <mapper class="mappers.StudentMapper" /> 
    <package name="com.mappers" /> 
  </mappers> 

最后是settings元素: 全局参数设置

settings元素有好多的参数设置

注意:大多数状况下,【这些参数使用它们的默认值便可】

<settings>
          <!-- 这个配置使全局的映射文件启用或禁用缓存 -->
          <setting name="cacheEnabled" value="true" />
          <!-- 全局启用或禁用延迟加载。当禁用时,全部关联对象都会即时加载 -->
          <setting name="lazyLoadingEnabled" value="true" />
          <!-- 容许或不容许多种结果集从一个单独的语句中返回(须要适合的驱动) -->
          <setting name="multipleResultSetsEnabled" value="true" /> 
          <!-- 使用列标签代替列名。不一样的驱动在这方便表现不一样。参考驱动文档或充分测试两种方法来决定所使用的驱动 -->
          <setting name="useColumnLabel" value="true" /> 
          <!-- 容许JDBC支持生成的键。须要适合的驱动。 -->
          <setting name="useGeneratedKeys" value="false" /> 
          <!-- 指定MyBatis如何自动映射列到字段/属性。PARTIAL只会自动映射简单、没有嵌套的结果。FULL会自动映射任意复杂的结果(嵌套的或其余状况) -->
          <setting name="autoMappingBehavior" value="PARTIAL" />
          <!-- 配置默认的执行器。SIMPLE执行器没有什么特别之处。REUSE执行器重用预处理语句。BATCH执行器重用语句和批量更新 -->
          <setting name="defaultExecutorType" value="SIMPLE" /> 
          <!-- 设置超时时间,它决定驱动等待一个数据库响应的时间 -->
          <setting name="defaultStatementTimeout" value="25000" />         
          <!-- 容许在嵌套语句中使用分页(RowBounds)默认false -->
          <setting name="safeRowBoundsEnabled" value="false" /> 
          <!-- 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的相似映射。默认false -->
          <setting name="mapUnderscoreToCamelCase" value="false" /> 
          <!-- MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种状况下会缓存一个会话中执行的全部查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不一样调用将不会共享数据。 -->
          <setting name="localCacheScope" value="SESSION" /> 
          <!-- 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动须要指定列的 JDBC 类型,多数状况直接用通常类型便可,好比 NULL、VARCHAR 或 OTHER。 -->
          <setting name="jdbcTypeForNull" value="NULL" />
          <!-- 指定对象的哪一个方法触发一次延迟加载。 -->
          <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode ,toString" /> 
          <!-- CGLIB | JAVASSIST 默认JAVASSIST(MyBatis 3.3 or above) -->
          <!-- 指定 Mybatis 建立具备延迟加载能力的对象所用到的代理工具。 -->
          <setting name="proxyFactory" value="JAVASSIST" /> 
          <!-- 当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性将会按需加载。 -->
          <setting name="aggressiveLazyLoading" value="true" />           
          <!-- 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 -->
          <setting name="logImpl" value="LOG4J " /> 
          <!-- 指定 MyBatis 增长到日志名称的前缀。值能够是任意字符串 -->
          <setting name="logPrefix" value="LOG4J " /> 
          <!-- 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这对于有 Map.keySet() 依赖或 null 值初始化的时候是有用的。注意基本类型(int、boolean等)是不能设置成 null 的。 默认false-->
          <setting name="callSettersOnNulls" value="false " /> 
</settings> 

拿其中的一个我认为最经常使用的,好比 <setting name="jdbcTypeForNull" value="NULL" /> 这个设置就能够有效的帮助咱们避免“1111”错误

这个配置是说若是当插入的值为空时给一个NULL属性,就避免了“1111”错误,好比我在将一个对象插入到表中的时候,一个属性没有值,在有些环境中数据库没法解析这个空的指向,就会报出“1111”错误,若是设置了这个属性这个空的指向就能够设为空

在package org.apache.ibatis.type包中中有一个枚举JdbcType,定义了一系列类型,可是一个数据库不可能彻底支持这些类型,源码以下:

package org.apache.ibatis.type;

import java.sql.Types;
import java.util.HashMap;
import java.util.Map;

/**
* @author Clinton Begin
*/
public enum JdbcType {
/*
* This is added to enable basic support for the
* ARRAY data type - but a custom type handler is still required
*/
ARRAY(Types.ARRAY),
BIT(Types.BIT),
TINYINT(Types.TINYINT),
SMALLINT(Types.SMALLINT),
INTEGER(Types.INTEGER),
BIGINT(Types.BIGINT),
FLOAT(Types.FLOAT),
REAL(Types.REAL),
DOUBLE(Types.DOUBLE),
NUMERIC(Types.NUMERIC),
DECIMAL(Types.DECIMAL),
CHAR(Types.CHAR),
VARCHAR(Types.VARCHAR),
LONGVARCHAR(Types.LONGVARCHAR),
DATE(Types.DATE),
TIME(Types.TIME),
TIMESTAMP(Types.TIMESTAMP),
BINARY(Types.BINARY),
VARBINARY(Types.VARBINARY),
LONGVARBINARY(Types.LONGVARBINARY),
NULL(Types.NULL),
OTHER(Types.OTHER),
BLOB(Types.BLOB),
CLOB(Types.CLOB),
BOOLEAN(Types.BOOLEAN),
CURSOR(-10), // Oracle
UNDEFINED(Integer.MIN_VALUE + 1000),
NVARCHAR(Types.NVARCHAR), // JDK6
NCHAR(Types.NCHAR), // JDK6
NCLOB(Types.NCLOB), // JDK6
STRUCT(Types.STRUCT),
JAVA_OBJECT(Types.JAVA_OBJECT),
DISTINCT(Types.DISTINCT),
REF(Types.REF),
DATALINK(Types.DATALINK),
ROWID(Types.ROWID), // JDK6
LONGNVARCHAR(Types.LONGNVARCHAR), // JDK6
SQLXML(Types.SQLXML), // JDK6
DATETIMEOFFSET(-155); // SQL Server 2008

public final int TYPE_CODE;
private static Map<Integer,JdbcType> codeLookup = new HashMap<Integer,JdbcType>();

static {
for (JdbcType type : JdbcType.values()) {
codeLookup.put(type.TYPE_CODE, type);
}
}

JdbcType(int code) {
this.TYPE_CODE = code;
}

public static JdbcType forCode(int code) {
return codeLookup.get(code);
}

}

经常使用的标签就这些了,这些标签的顺序为

properties,settings,typeAliases,typeHandlers,environments,mappers

有任何不足的地方欢迎你们指出,我会学习而且修改

相关文章
相关标签/搜索