配置文件的有序结构
<?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="" value=""/>
</properties>
<!--设置-->
<settings>
<setting name="" value=""/>
</settings>
<!--别名-->
<typeAliases>
<typeAlias alias="" type=""/>
<package name=""/>
</typeAliases>
<!--类型处理器-->
<typeHandlers>
<typeHandler handler=""/>
<package name=""/>
</typeHandlers>
<!--对象工厂-->
<objectFactory type="">
<property name="" value=""/>
</objectFactory>
<!--插件-->
<plugins>
<plugin interceptor=""/>
</plugins>
<!--所有的数据库环境环境-->
<environments default="">
<!--某个数据库环境-->
<environment id="">
<!--事务管理器-->
<transactionManager type=""/>
<!--数据源-->
<dataSource type=""/>
</environment>
</environments>
<!--数据库厂商标识-->
<databaseIdProvider type="">
<property name="" value=""/>
</databaseIdProvider>
<!--映射器-->
<mappers>
<mapper resource=""/>
<mapper class=""/>
<package name=""/>
</mappers>
</configuration>
properties配置
这个元素中可以配置属性和属性值,以在多个配置文件中重复使用。除了上面有序结构中展示的property
子元素配置方法之外,还可以使用:
<properties resource="xxx.properties"/>
这样就能将这个.properties
配置文件中的name=value
形式的属性导入到这个配置文件中了,这是书上作者最推荐的方式。
如果要在配置文件中使用properties
元素所配置的某个属性,只需要"${属性name}"
即可取到配置的属性value。
书上还讲了配置文件中配置的往往是加密的数据库信息,可以用程序参数传递的方式,在传递时使用decode()
函数解密,满足对系统安全性的需求。
配置属性有
- property子元素
- properties配置文件
- 程序参数传递
三种方式,从上到下优先级依次增加,即高优先级的后加载、高优先级的属性会覆盖低优先级的同名属性。
settings配置
这个元素里的设置会改变MyBatis运行时的行为,当不作配置时,其默认配置相当于:
<!--设置(默认值)-->
<settings>
<!--使用列标签代替别名(是)-->
<setting name="useColumnLabel" value="true"/>
<!--允许JDBC支持自动生成主键(否)-->
<setting name="useGeneratedKeys" value="false"/>
<!--如何自动映射列到字段或属性-->
<!--NONE:取消自动映射;PARTIAL:只映射没有嵌套结果集的;FULL:再复杂的结果集都会被映射-->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!--配置默认的执行器-->
<!--SIMPLE:普通执行器;REUSE:重用PreparedStatement;BATCH:REUSE+批量更新-->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!--驱动等待数据库响应的超时时间秒数(不配置即使用默认时间)-->
<setting name="defaultStatementTimeout" value=""/>
<!--允许在嵌套语句中使用RowBounds分页(否)-->
<setting name="safeRowBoundsEnabled" value="false"/>
<!--开启自动驼峰命名,如表中列A_COLUMN映射为属性aColumn(否)-->
<setting name="mapUnderscoreToCamelCase" value="false"/>
<!--本地缓存用于防止循环引用和加速重复嵌套查询,这里是其范围-->
<!--SESSION:缓存一个会话中执行的所有查询;STATEMENT:本地缓存仅用在语句执行上,使相同SqlSession的调用不共享数据-->
<setting name="localCacheScope" value="SESSION"/>
<!--没有为参数提供特定的JDBC类型时,为空值指定JDBC类型,其值需是jdbcType枚举-->
<setting name="jdbcTypeForNull" value="OTHER"/>
<!--指定会触发延迟加载的方法-->
<setting name="lazyLoadTriggerMethod" value="equals,clone,hashCode,toString"/>
<!--指定动态SQL生成的默认语言,书上说默认是XMLDynamicLanguageDriver,但我没找到这个类,只找到下面这个-->
<setting name="defaultScriptingLanguage" value="org.apache.ibatis.scripting.xmltags.XMLLanguageDriver"/>
<!--当结果集中值为null时是否调用映射对象的setter(否)-->
<setting name="callSettersOnNulls" value="false"/>
<!--MyBatis增加到日志名称的前缀(无)-->
<setting name="logPrefix" value=""/>
<!--MyBatis所用日志的具体实现(未指定时自动查找)-->
<!--SLF4J,LOG4J,LOG4J2,JDK_LOGGING,COMMONS_LOGGING,STDOUT_LOGGING,NO_LOGGING-->
<setting name="logImpl" value=""/>
<!--指定MyBatis创建具有延迟加载能力的对象所用到的代理工具(3.3.0及以上用JAVASSIST,其以下用CGLIB)-->
<setting name="proxyFactory" value="JAVASSIST"/>
</settings>
实际使用时只要去配置不使用默认配置的那些配置即可。
typeAliases配置
配置元素typeAliases
用来配置别名,以代替一个很长的类的全限名。从org.apache.ibatis.type.TypeAliasRegistry
类的构造器可以看到一些系统定义别名:
public TypeAliasRegistry() {
this.registerAlias("string", String.class);
this.registerAlias("byte", Byte.class);
this.registerAlias("long", Long.class);
this.registerAlias("short", Short.class);
this.registerAlias("int", Integer.class);
this.registerAlias("integer", Integer.class);
this.registerAlias("double", Double.class);
this.registerAlias("float", Float.class);
this.registerAlias("boolean", Boolean.class);
this.registerAlias("byte[]", Byte[].class);
this.registerAlias("long[]", Long[].class);
this.registerAlias("short[]", Short[].class);
this.registerAlias("int[]", Integer[].class);
this.registerAlias("integer[]", Integer[].class);
this.registerAlias("double[]", Double[].class);
this.registerAlias("float[]", Float[].class);
this.registerAlias("boolean[]", Boolean[].class);
this.registerAlias("_byte", Byte.TYPE);
this.registerAlias("_long", Long.TYPE);
this.registerAlias("_short", Short.TYPE);
this.registerAlias("_int", Integer.TYPE);
this.registerAlias("_integer", Integer.TYPE);
this.registerAlias("_double", Double.TYPE);
this.registerAlias("_float", Float.TYPE);
this.registerAlias("_boolean", Boolean.TYPE);
this.registerAlias("_byte[]", byte[].class);
this.registerAlias("_long[]", long[].class);
this.registerAlias("_short[]", short[].class);
this.registerAlias("_int[]", int[].class);
this.registerAlias("_integer[]", int[].class);
this.registerAlias("_double[]", double[].class);
this.registerAlias("_float[]", float[].class);
this.registerAlias("_boolean[]", boolean[].class);
this.registerAlias("date", Date.class);
this.registerAlias("decimal", BigDecimal.class);
this.registerAlias("bigdecimal", BigDecimal.class);
this.registerAlias("biginteger", BigInteger.class);
this.registerAlias("object", Object.class);
this.registerAlias("date[]", Date[].class);
this.registerAlias("decimal[]", BigDecimal[].class);
this.registerAlias("bigdecimal[]", BigDecimal[].class);
this.registerAlias("biginteger[]", BigInteger[].class);
this.registerAlias("object[]", Object[].class);
this.registerAlias("map", Map.class);
this.registerAlias("hashmap", HashMap.class);
this.registerAlias("list", List.class);
this.registerAlias("arraylist", ArrayList.class);
this.registerAlias("collection", Collection.class);
this.registerAlias("iterator", Iterator.class);
this.registerAlias("ResultSet", ResultSet.class);
}
在配置自定义别名时应绕开这些系统已经定义好的别名。
如果仅仅使用typeAlias
子元素配置别名,当要配置的别名很多时会导致配置文件很大。可以使用package
子元素指明要扫描的包,包下的要配置别名的类使用@Alias
注解,如:
<typeAliases>
<package name="model"/>
</typeAliases>
package model;
import org.apache.ibatis.type.Alias;
@Alias("student")
public class Student {
//...
}
即成功为model.Student这个类配置了别名为student,该包下的其它类也会被扫描并配置别名。扫描中即使遇到没有打上@Alias
注解的类,也会将其类名的第一个字母小写,以配置为该类的别名。