mybatis配置XML文件的层次结构:
(注意,这些层次是不能够颠倒顺序的,如果颠倒顺序,mybatis在解析XML文件的时候就会出现异常)
<?xml version="1.0" encoding="UTF-8"?> <configuration><!-- 配置 --> <properties/><!-- 属性 --> <settings/><!-- 设置 --> <typeAliases/><!-- 类型命名 --> <typeHandlers/><!-- 类型处理器 --> <objectFactory/><!-- 对象工厂 --> <plugins/><!-- 插件 --> <environments><!-- 配置环境 --> <environment><!-- 环境变量 --> <transactionManager/><!-- 事务管理器 --> <dataSoure/><!-- 数据源 --> </environment> </environments> <databaseIdProvider/><!-- 数据库厂商标识 --> <mappers/><!-- 映射器 --> </configuration>
3.1 properties元素
mybatis提供3中配置方式
-
property子元素
-
properties配置文件
-
程序参数传递
3.1.1 property子元素
在properties标签下的property标签中引入drver、url、username、password后,在dataSource中使用${driver}
${url} —就是以美元符号+{} 的形式得到数据库连接的相关信息。
3.1.2 properties配置文件
properties文件的使用:
#数据库配置文件 diver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis username=root password=learn
把这个properties文件放在源包下,只要这样引入这个配置文件即可。
<properties resource = "jdbc.properties"/>
3.1.3 程序参数传递
假设jdbc.properties文件中的username和password两个属性使用了加密的字符串,这个时候我们需要生成SqlSessionFactory之前将它转化为明文,而系统已经提供了解密的方法decode(str)
3.1.4 优先级
mybatis支持的三种配置方式可能同时出现,并且属性还会重复配置。这三种方式是存在优先级的,mybatis将按照下面的顺序来加载。
-
在properties元素体内指定的属性首先被读取。
-
根据properties元素中的resource属性读取类路径下属性文件,或者根据URL属性指定的路径读取属性文件,并覆盖已读取的同名属性。
-
读取作为方法参数传递的属性,并覆盖已读取的同名属性。
根据以上优先级,实际操作中我们需要注意一下三点:
-
不要使用混合的方式,会造成管理混乱。
-
首选使用properties文件。
-
如果我们需要对其进行加密或者其他加工以满足特殊的要求,不妨按示例的方法处理。这样做的好处是使得配置都来自于同一个配置文件,就不容易产生没有必要的歧义,也为日后统一管理提供了方便。
-
3.2 设置
setting在mybatis中是最复杂的配置,同时也是最重要的配置内容之一,它会改变mybatis运行时的行为。即使不配置settings,mybatis也可以正常的工作。但是了解settings的配置内容以及它们的作用仍然十分重要。
settings的配置内容
设置参数 | 描述 | 有效值 | 默认值 |
---|---|---|---|
cacheEnabled | 该配置影响所有映射器中配置的缓存全局开关 | True /false | True |
lazyLoadingEnabled | 延迟加载的全局开关,当它开启时,所有关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态 | true、false | false |
aggressiveLazyLoading | 当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性将会按需加载 | true、false | true |
multipleResultSetsEnabled | 是否允许单一语句返回多结果集(需要兼容驱动) | true、false | true |
useColumnLabel | 使用列标签代替列名,不同的驱动在这方面会有不同的表现,具体可以参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。 | true、false | true |
useGeneratedKeys | 允许JDBC支持自动生成主键,需要驱动兼容。如果设置为true,则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如Derby) | true、false | false |
autoMappingBehavior | 指定mybatis应如何自动映射到字段或属性。NONE表示取消自动映射;PARTIAL只会自动映射没有定义嵌套结果集映射的结果集;FULL会自动映射任意复杂的结果集(无论是否嵌套) | NONE、PARTIAL、FULL | PARTIAL |
defaultExecutorType | 配置默认的执行器。SIMPLE是普通的执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 | SIMPLE、REUSE、BATCH | SIMPLE |
defaultStatementTimeout | 设置超时时间,它决定驱动等待数据库响应的秒数。当没有设置的时候它取的就是驱动默认的时间 | Any positive integer | Not set(null) |
safeRowBoundsEnabled | 允许在嵌套语句中使用分页(RowBounds) | true、false | false |
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枚举,最常见的是NULL、VARCHAR和OTHER | OTHER |
lazyLoadTriggerMethods | 指定对象的方法触发一次延迟加载 | 如果是一个方法列表,我们则用逗号将它们隔开 | equals、clone、hashCode、toString |
defaultScriptingLanguage | 指定动态SQL生成的默认语言 | 你可以配置类的别名或者类的全限定名 | |
callSettersOnNulls | 指定当结果集中值为null的时候是否调用映射对象setter(map对象时为put)方法,这对于有Map.keySet()依赖或null值初始化的时候是有用的。注意基本类型(int、boolean等)是不能设置成null的 | true、false | false |
logPrefix | 指定mybatis增加到日志名称的前缀 | 任何字符串 | 没有设置 |
logImpl | 指定mybatis所用日志的具体实现,未指定时将自动查找 | ||
proxyFactory | 指定mybatis创建具有延时加载能力的对象所用到的代理工具 | CGLIB、JAVASSIST |
一个完整的配置
<settings> <setting name="cacheEnable" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> <setting name="multipleResultSetEnabled" value="true"/> <setting name="useColumnLable" value="true"/> <setting name="useGeneratedKeys" value="false"/> <setting name="autoMappingBehavior" value="PARTIAL"/> <setting name="defaultExecutorType" value="SIMPLE"/> <setting name="defaultStatementTimeout" value="25"/> <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>
3.3 别名
别名(typeAliases)是一个指代的名称。因为我们遇到的类全限定名过长,所以我们希望用一个简短的名称去指代它,而这个名称可以在mybatis上下文中使用。别名在mybatis里面分为系统定义别名和自定义别名两类。注意,在mybatis中别名是部分大小写的。一个tyoeAliases的实例是在解析配置文件时生成的,然后长期保存在Configuration对象中,当我们使用它时,再把它拿出来,这样就没有必要运行的时候再次生成它的实例了。
3.3.1 系统定义别名
3.3.2 自定义别名
<!-- 定义别名 --> <typeAliases> <typeAlias alias="role" type="com.learn.chapter.po.Role"/> </typeAliases>
这样我们就可以在mybatis的上下文中使用"role"来代替其全路径,减少配置的复杂度。
<!-- 自定义别名 --> <typeAliases> <package name="com.learn.chapter2.po"/> <package name="com.learn.chapter3.po"/> </typeAliases>
我们需要自己定义别名,它是使用注解@Alias,这里我们定义角色类的别名为role,实现的伪代码如下:
@Alias("role") public class Role{ // some code }
3.4 typeHandler类型处理器
typeHandler常用的配置为Java类型(JavaType)、JDBC类型(jdbcType)。typeHandler的作用就是将参数从JavaType转化为jdbcType,或者从数据库取出结果时把jdbcType转化为javaType。
3.4.1 系统定义的typeHandler
我们需要注意下面几点:
-
数值类型的精度,数据库int,double、decimal这些类型和java的精度、长度都是不一样的。
-
时间精度,取数据到日用DataOnlyTypeHandler即可,用到精度为秒的用SqlTimestampTypeHandler等。
3.4.2 自定义typeHandler
自定义typeHandler里用注解配置JdbcType和JavaType。这两个注解是:
-
@MappedTypes定义的是JavaType类型,可以指定哪些Java类型被拦截。
-
@MappedJdbcTypes定义的是JdbcType类型,它需要满足枚举类org.apache.ibatis.type.JdbcType所列的枚举类型。
resultMap提供了映射规则,这里给了三种typeHandler的使用方法。
-
在配置文件里配置,在结果集的roleName定义jdbcType和javaType。只有定义的jdbcType、javaType和我们定义在配置里面的typeHandler是一致的,mybatis才能够知道用我们自定义的类型转化器进行转换。
-
映射集里面直接定义具体的typeHandler,这样就不需要再在配置里面定义了。
-
在参数中指定typeHandler,这样mybatis就会用对应的typeHandler进行转换,这样也不需要在配置里面定义了。
3.4.3 枚举类型typeHandler
mybatis内部提供了两个转化枚举类型的typeHandler:
-
org.apache.ibatis.EnumTypeHandler,使用枚举字符串名称作为参数传递的
-
org.apache.ibatis.type.EnumOrdinalTypeHandler,使用整数下标作为参数传递的
3.5 ObjectFactory
当mybatis在构建一个结果返回的时候,都会使用ObjectFactory(对象工厂)去构建POJO,在mybatis中可以定制自己的对象工厂。一般来说我们使用默认的ObjectFactory即可,mybatis中默认的ObjectFactory是由org.apache.ibatis.reflection.factory.DefaultObjectFactory来提供服务的。在大部分的场景下我们都不用修改。
3.6 插件
比较复杂。使用插件会覆盖一些mybatis内部核心对象的行为。
3.7 environment配置环境
3.7.1 概述
配置环境可以注册多个数据源(DataSource),每一个数据源分为两大部分:一个是数据库源的配置,另外一个是数据库事务(transactionManager)的配置。
配置数据源
<environment default="development"> <environment id="development"> <transactionManager type="JDBC"> <property name="autoCommit" value="false"/> </transactionManager> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/oa"/> <property name="username" value="root"/> <property name="password" value="learn"/> </dataSource> </environment> </environment>
分析:
-
environments中的属性default,标明在缺省的情况下,我们将启用哪个数据源配置。
-
environment元素是配置一个数据源的开始,属性id是设置这个数据源的标志,以便mybatis上下文使用它。
-
transactionManager配置的是数据库事务,其中type属性有三种配置方式。
-
JDBC,采用JDBC方式管理事务,在JNDI数据源中常用。
-
MANAGED,采用容器方式管理事务,在JNDI数据源中常用。
-
自定义,由使用者自定义数据库事务管理办法,适用于特殊应用。
-
-
property元素则是可以配置数据源的各类属性,我们这里配置的autoCommit=false,则是要求数据源不自动提交。
-
dataSource标签,是配置数据源连接的信息,type属性是提供我们队数据库连接方式的配置,同样mybatis提供几种配置方式:
-
UNPOOLED,非连接池数据库(UnpooledDataSource)
-
POOLED,连接池数据库(PooledDataSource)
-
JNDI,JNDI数据源(JNDIDataSource)
-
自定义数据源
其中,配置的property元素,就是定义数据库的各类参数。
-
3.7.2 数据库事务
数据库事务mybatis是交由SqlSession去控制的,我们可以通过SqlSession提交或者回滚。我们插入一个角色对象,如果成功就提价破,否则就回滚。
大部分的工作环境下,我们都会使用Spring框架来控制它。
3.7.3 数据源
三种数据源的实现方式:
-
UNPOOLED
-
POOLED
-
JNDI
3.8 databaseIdProvider 数据库厂商标识
mybatis可能运行在不同厂商的数据库中,它为此提供一个数据库标识,并提供自定义,它的作用在于指定SQL到对应的数据库厂商提供的数据库中运行。
3.8.1 使用系统默认规则
在多了一个databaseId属性的情况下,mybatis将提供如下规则:
-
如果没有配置databaseIdProvider标签,那么databaseId就会返回null。
-
如果配置了databaseIdProvider标签,mybatis就会用配置的name值去匹配数据库信息,如果匹配得上就会设置databaseId,否则依旧为null。
-
如果Configuration的databaseId不为空,则它只会找到配置databaseId的SQL语句。
-
mybatis会加载databaseId属性和带有匹配当前数据库databaseId属性的所有语句。如果同时找到带有databaseId和不带databaseId的相同语句,则后者会被舍弃。
3.8.2 不使用系统默认规则
3.9 引入映射器的方法
1.用文件路径引入映射器
<mappers> <mapper resource="com/learn/chapter3/mapper/roleMapper.xml"></mapper> </mappers>
2.用包名引入映射器
<mappers> <package name="com.learn.chapter3.mapper"/> </mappers>
3.用类注册引入映射器
<mappers> <mapper class="com.learn.chapter3.mapper.UserMapper"/> <mapper class="com.learn.chapter3.mapper.RoleMapper"/> </mappers>
4.用userMapper.xml引入映射器
<mappers> <mapper url="file:///var/mappers/com/learn/chapter3/mapper/roleMapper.xml"/> <mapper url="file:///var/mappers/com/learn/chapter3/mapper/RoleMapper.xml"/> </mappers>