Mybatis配置文件详解
Mybatis配置文件层次结构,层次结构顺序不能改变,否则会报错。
<configuration><!-- 配置 -->
<properties/><!-- 属性 -->
<settings><!-- 设置 -->
<setting name="" value=""/>
</settings>
<typeAliases/><!-- 类型命名 -->
<typeHandlers/><!-- 类型处理器 -->
<objectFactory type=""/><!-- 对象工厂 -->
<plugins><plugin interceptor=""></plugin></plugins><!-- 插件 -->
<environments default=""><!-- 配置环境 -->
<environment id=""><!-- 环境变量 -->
<transactionManager type=""></transactionManager><!-- 事务管理器 -->
<dataSource type=""></dataSource><!-- 数据源 -->
</environment>
</environments>
<databaseIdProvider type=""/><!-- 数据库厂商标识 -->
<mappers/><!-- 映射器 -->
</configuration>
Properties子元素
Properties元素是配置属性的,可以在配置文件的上下文中使用它。
三种方式设置Properties:
- Property子元素
- Properties配置文件(建议使用)
- 程序参数传递
- 三种方式的优先级:
先加载property子元素;后加载properties配置文件,如果属性相同,properties的属性值会覆盖property元素的值;最后加载程序参数传递,如果属性相同,程序中的值会覆盖properties配置文件的属性值。
设置(settings)
设置是Mybatis中最复杂的配置,同时也是最重要的配置内容之一,它会改变Mybatis运行时的行为。
Settings的配置内容如下:
设置参数 | 描述 | 有效值 | 默认值 |
---|---|---|---|
cacheEnabled | 该配置影响的所有映射器中配置的缓存的全局开关。 | true | false | true |
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。 | true | false | false |
aggressiveLazyLoading | 当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载(参考lazyLoadTriggerMethods). | true | false | false (true in ≤3.4.1) |
multipleResultSetsEnabled | 是否允许单一语句返回多结果集(需要兼容驱动)。 | true | false | true |
useColumnLabel | 使用列标签代替列名。不同的驱动在这方面会有不同的表现, 具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。 | true | false | true |
useGeneratedKeys | 允许 JDBC 支持自动生成主键,需要驱动兼容。 如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。 | true | false | False |
autoMappingBehavior | 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套)。 | NONE, PARTIAL, FULL | PARTIAL |
autoMappingUnknownColumnBehavior | 指定发现自动映射目标未知列(或者未知属性类型)的行为。
| NONE, WARNING, FAILING | NONE |
defaultExecutorType | 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。 | SIMPLE REUSE BATCH | SIMPLE |
defaultStatementTimeout | 设置超时时间,它决定驱动等待数据库响应的秒数。 | 任意正整数 | Not Set (null) |
defaultFetchSize | 为驱动的结果集获取数量(fetchSize)设置一个提示值。此参数只可以在查询设置中被覆盖。 | 任意正整数 | Not Set (null) |
safeRowBoundsEnabled | 允许在嵌套语句中使用分页(RowBounds)。 If allow, set the false. | true | false | False |
safeResultHandlerEnabled | 允许在嵌套语句中使用分页(ResultHandler)。 If allow, set the false. | true | false | True |
mapUnderscoreToCamelCase | 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 | true | false | False |
localCacheScope | MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。 | SESSION | STATEMENT | SESSION |
jdbcTypeForNull | 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。 | JdbcType enumeration. Most common are: NULL, VARCHAR and OTHER | OTHER |
lazyLoadTriggerMethods | 指定哪个对象的方法触发一次延迟加载。 | A method name list separated by commas | equals,clone,hashCode,toString |
defaultScriptingLanguage | 指定动态 SQL 生成的默认语言。 | A type alias or fully qualified class name. | org.apache.ibatis.scripting.xmltags.XMLLanguageDriver |
callSettersOnNulls | 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这对于有 Map.keySet() 依赖或 null 值初始化的时候是有用的。注意基本类型(int、boolean等)是不能设置成 null 的。 | true | false | false |
returnInstanceForEmptyRow | 当返回行的所有列都是空时,MyBatis默认返回null。 当开启这个设置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集 (i.e. collectioin and association)。(从3.4.2开始) | true | false | false |
logPrefix | 指定 MyBatis 增加到日志名称的前缀。 | Any String | Not set |
logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | Not set |
proxyFactory | 指定 Mybatis 创建具有延迟加载能力的对象所用到的代理工具。 | CGLIB | JAVASSIST | JAVASSIST (MyBatis 3.3 or above) |
vfsImpl | 指定VFS的实现 | 自定义VFS的实现的类全限定名,以逗号分隔。 | Not set |
useActualParamName | 允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,你的工程必须采用Java 8编译,并且加上-parameters选项。(从3.4.1开始) | true | false | true |
configurationFactory | Specifies the class that provides an instance of Configuration. The returned Configuration instance is used to load lazy properties of deserialized objects. This class must have a method with a signature static Configuration getConfiguration(). (Since: 3.2.3) | A type alias or fully qualified class name. | Not set |
一个完整的settings示例如下:
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<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>
类型别名(typeAliases)
别名是一个指代的名称。这个名称可以在Mybatis上下文使用。
别名分为两类:系统定义别名、自定义别名。
Mybatis中别名是不区分大小写的。
系统定义别名
常用的类型别名:
别名 映射的类型 支持数组
别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
自定义别名
- 使用typeAliases配置别名:
<typeAliases>
<typeAlias type="com.shop.Role" alias="role"/>
</typeAliases>
代表:com.shop.Role的别名为:role
- 代码注册别名:
<typeAliases>
<package name="com.shop"/>
</typeAliases>
@Alias(“role”)
public class Role {
}
代表:扫描包com.shop,使用注解@Alias;不使用@Alias注解,则将类名的第一个字母变小写作为别名。
typeHandler类型处理器
Mybatis在预处理语句(PreparedStatement)中设置一个参数时,或者从结果集(ResultSet)中取出一个值时,都会用注册了的typeHandler进行处理。
TypeHandler分为两种:系统定义和用户自定义。
TypeHandler常用的配置为Java类型(javaType)、JDBC类型(jdbcType)。TypeHandler的作用就是将参数从javaType转化为jdbcType,或者从数据库取出结果时把jdbcType转化为javaType。
系统定义的typeHandler
类型处理器 | Java 类型 | JDBC 类型 |
---|---|---|
BooleanTypeHandler | java.lang.Boolean, boolean | 数据库兼容的 BOOLEAN |
ByteTypeHandler | java.lang.Byte, byte | 数据库兼容的 NUMERIC 或 BYTE |
ShortTypeHandler | java.lang.Short, short | 数据库兼容的 NUMERIC 或 SHORT INTEGER |
IntegerTypeHandler | java.lang.Integer, int | 数据库兼容的 NUMERIC 或 INTEGER |
LongTypeHandler | java.lang.Long, long | 数据库兼容的 NUMERIC 或 LONG INTEGER |
FloatTypeHandler | java.lang.Float, float | 数据库兼容的 NUMERIC 或 FLOAT |
DoubleTypeHandler | java.lang.Double, double | 数据库兼容的 NUMERIC 或 DOUBLE |
BigDecimalTypeHandler | java.math.BigDecimal | 数据库兼容的 NUMERIC 或 DECIMAL |
StringTypeHandler | java.lang.String | CHAR, VARCHAR |
ClobReaderTypeHandler | java.io.Reader | - |
ClobTypeHandler | java.lang.String | CLOB, LONGVARCHAR |
NStringTypeHandler | java.lang.String | NVARCHAR, NCHAR |
NClobTypeHandler | java.lang.String | NCLOB |
BlobInputStreamTypeHandler | java.io.InputStream | - |
ByteArrayTypeHandler | byte[] | 数据库兼容的字节流类型 |
BlobTypeHandler | byte[] | BLOB, LONGVARBINARY |
DateTypeHandler | java.util.Date | TIMESTAMP |
DateOnlyTypeHandler | java.util.Date | DATE |
TimeOnlyTypeHandler | java.util.Date | TIME |
SqlTimestampTypeHandler | java.sql.Timestamp | TIMESTAMP |
SqlDateTypeHandler | java.sql.Date | DATE |
SqlTimeTypeHandler | java.sql.Time | TIME |
ObjectTypeHandler | Any | OTHER 或未指定类型 |
EnumTypeHandler | Enumeration Type | VARCHAR-任何兼容的字符串类型,存储枚举的名称(而不是索引) |
EnumOrdinalTypeHandler | Enumeration Type | 任何兼容的 NUMERIC 或 DOUBLE 类型,存储枚举的索引(而不是名称)。 |
注意以下几点:
数值类型的精度,数据库int、double、decimal这些类型和Java的精度、长度都是不一样的。
时间精度,取数据到日用DateOnlyTypeHandler即可,用到精度为秒的用SqlTimestampTypeHandler等。
用户自定义typeHandler
必须实现接口:TypeHandler.(也可以继承BaseTypeHandler,BaseTypeHandler已经实现了TypeHandler接口)
自定义typeHandler里用注解配置JdbcType和JavaType。注解是:
- @MappedTypes 定义的是JavaType类型,可以指定哪些Java类型被拦截。
- @MappedJdbcTypes 定义的是JdbcType类型,需要满足枚举类org.apache.ibatis.type.JdbcType所列的枚举类型。
枚举类型typeHandler
Mybatis中枚举类型的typeHandler有自己的特殊规则,Mybatis内部提供了两个转化枚举类型的typeHandler。
Org.apache.ibatis.type.EnumTypeHandler
Org.apache.ibatis.type.EnumOrdinalTypeHandler
EnumTypeHandler是使用枚举字符串名称作为参数传递的,EnumOrdinalTypeHandler使用整数下标作为参数传递的。
ObjectFactory
当Mybatis在构建一个结果返回的时候,都会使用ObjectFactory(对象工厂)去构建POJO,在Mybatis中可以构建自己的工厂。一般来说我们使用默认的ObjectFactory即可,Mybatis中默认的ObjectFactory是由org.apache.ibatis.reflection.factory.DefaultObjectFactory来提供服务的。
定制特定的工厂
<objectFactory type=”com.learn.chapter03.objectFactory.MyObjectFactory”>
<property name=”name” value=”MyObjectFactory”/>
</objectFatory>
- 自定义工厂—条件:
实现ObjectFactory接口。(可以通过继承DefaultObjectFactory简化编程)。
插件
Environments配置环境
配置环境可以注册多个数据源(DataSource)。每个数据源分为两部分:一个是数据库源的配置;一个是数据库事务(transactionManager)的配置。
<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>
Environments中的属性default,表明在缺省的情况下,启用哪个数据源配置。
Environment元素是配置一个数据源的开始,属性id是设置这个数据源的标志,以便Mybatis上下文使用它。
transactionManager配置的是数据库事务,其中type有3种配置方式:
JDBC,采用JDBC管理事务,在独立编码中常常使用。
MANAGED,采用容器方式管理事务,在JNDI数据源中常用。
自定义,由使用者定义数据库事务管理方法,适用于特殊应用。
Property元素则是可以配置数据源的各类属性,我们这里可以配置autoCommit=false,要求数据源不自动提交。
DataSource标签,是配置数据源连接的信息,type属性是提供我们对数据库连接方式的配置,同样Mybatis提供这么几种配置方式:
UNPOOLED,非连接池数据库(UnpooledDataSource)
POOLED,连接池数据库(PooledDataSource)
JNDI,JNDI数据源(JNDIDataSource)
自定义数据源
其中,配置的property元素,就是定义数据库的各类参数。
数据库事务Mybatis是交由SqlSession去控制的,可以通过SqlSession提交或者回滚。
数据源
Mybatis内部为我们提供了3种数据源的实现方式:
- UNPOOLED,非连接池,使用Mybatis提供的org.apache.ibatis.datasouce.unpooled.UnpooledDataSource实现。
- POOLED,连接池,使用Mybatis提供的org.apache.ibatis.datasource.pooled.PooledDataSource实现。
- JNDI,使用Mybatis提供的org.apache.ibatis.datasource.jndi.JndiDataSourceFactory获取数据源。
只需要把数据源的属性type属性定义为UNPOOLED,POOLED,JNDI即可。
自定义数据源:必须实现ora.apache.ibatis.datasource.DataSourceFactory接口即可。配置自定义数据源:<datasource type=”XXX.XXX.XXDataSourceFactory”>。
DatabaseIdProvider数据库厂商标识
相同的数据库厂商的环境下,数据库厂商标识没什么意义。但Mybatis可能会运行在不同厂商的数据库中,它为此提供一个数据标识,并提供自定义,它的作用在于指定SQL到对应的数据库厂商提供的数据库中运行。
使用系统默认规则
<databaseIdProvider type="DB_VENDOR">
<property name="SQL Server" value="sqlserver"/>
<property name="DB2" value="db2"/>
<property name="Oracle" value="oracle" />
</databaseIdProvider>
type=”DB_VENDOR”是启动Mybatis内部注册的策略器。首先Mybatis会将你的配置读入Configuration类中,在连接数据库后调用getDatabaseProductName()方法去获取数据库的信息,然后用我们配置的name值去做匹配来得到DatabaseId。可以指定SQL在哪个数据厂商执行。
不使用系统默认规则
Mybatis提供规则允许自定义,需要实现DatabaseIdProvider接口,并且实现配置即可。
<databaseIdProvider type="全限定名自定义类">
<property name="SQL Server" value="sqlserver"/>
<property name="DB2" value="db2"/>
<property name="Oracle" value="oracle" />
</databaseIdProvider>
引入映射器的方法
映射器是Mybatis最复杂、最核心的组件。映射器定义的命名空间是一个接口的全路径,而不是实现类。
引入映射器的方法很多,一般分为以下几种:
用文件路径引入映射器
<mappers>
<mapper resource=”com/learn/chapter03/mapper/roleMapper.xml”/>
</mappers>
用包名引入映射器
<mappers>
<package name=”com.learn.chapter03.mapper”>
</mappers>
用类注册引入映射器
<mappers>
<mapper class="com.learn.chapter03.mapper.UserMapper"/>
<mapper class="com.learn.chapter03.mapper.RoleMapper"/>
</mappers>
用userMapper.xml引入映射器
<mappers>
<mapper url=”file:///var/mappers/com/learn/chapter03/mapper/RoleMapper.xml” />
</mappers>
根据需要选择合适的引入方法。