MyBatis的XML配置文件包含了影响MyBatis行为甚深的设置和属性信息。XML文档的高层级结构如下:
configuration配置
properties属性
settings设置
typeAliases类型命名
typeHandlers类型处理器
objectFactory对象工厂
plugins插件
environments环境
environment环境变量
transactionManager事务管理器
dataSource数据源
映射器(mappers)
properties
这些是外部化的,可替代的属性,这些属性也可以配置在典型的Java属性配置文件中,或者通过properties元素的子元素来传递。如:
- <properties resource="org/mybatis/example/config.properties">
- <property name="username" value="dev_user"/>
- <property name="password" value="dev_user"/>
- </properties>
属性也可以被传递到SqlSessionBuilder.build()方法中。例如:
- SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, props);
- SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment, props);
(1)在properties元素体内指定的属性首先被读取。
(2)从类路径下资源或properties元素的url属性中加载的属性第二被读取,它会覆盖已经存在的完全一样的属性。
(3)作为方法参数传递的属性最后被读取,它也会覆盖任一已经存在的完全一样的属性,这些属性可能是从properties元素体内和资源/url属性中加载的。
因此,最高优先级的属性是那些作为方法参数的,然后是资源/url属性,最后是properties元素中指定的属性。
Settings
这些是极其重要的调整,它们会修改MyBatis在运行时的行为方式。
设置参数 |
描述 |
有效值 |
默认值 |
cacheEnabled |
这个配置使全局的映射器启用或禁用缓存。 |
true | false |
true |
lazyLoadingEnabled |
全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 |
true | false |
true |
aggressiveLazyLoading |
当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 |
true | false |
true |
multipleResultSetsEnabled |
允许或不允许多种结果集从一个单独的语句中返回(需要适合的驱动)。 |
true | false |
true |
useColumnLabel |
使用列标签代替列名。不同的驱动在这方便表现不同。参考驱动文档或充分测试两种方法来决定所使用的驱动。 |
true | false |
true |
useGeneratedKeys |
允许JDBC支持生成的键。需要适合的驱动。如果设置为true则这个设置强制生成的键被使用,尽管一些驱动拒绝兼容但仍然有效(比如Derby)。 |
true | false |
false |
autoMappingBehavior |
指定MyBatis如何自动映射列到字段/属性。PARTIAL只会自动映射简单,没有嵌套的结果。FULL会自动映射任意复杂的结果(嵌套的或其他情况)。 |
NONE, PARTIAL, FULL |
PARTIAL |
defaultExecutorType |
配置默认的执行器。SIMPLE执行器没有什么特别之处。REUSE执行器重用预处理语句。BATCH执行器重用语句和批量更新 |
SIMPLE, REUSE, BATCH |
SIMPLE |
defaultStatementTimeout |
设置超时时间,它决定驱动等待一个数据库响应的时间。 |
任何正整数 |
Not Set (null) |
一个设置信息元素的示例,完全的配置如下所示:
- <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="enhancementEnabled" value="false" />
- <setting name="defaultExecutorType" value="SIMPLE" />
- <setting name="defaultStatementTimeout" value="25000" />
- </settings>
typeAliases
类型别名是为Java类型命名一个短的名字。它只和XML配置有关,只用来减少类完全限定名的多余部分。
如:
- <typeAliases>
- <typeAlias alias="Author" type="domain.blog.Author"/>
- <typeAlias alias="Blog" type="domain.blog.Blog"/>
- <typeAlias alias="Comment" type="domain.blog.Comment"/>
- <typeAlias alias="Post" type="domain.blog.Post"/>
- <typeAlias alias="Section" type="domain.blog.Section"/>
- <typeAlias alias="Tag" type="domain.blog.Tag"/>
- </typeAliases>
typeHandlers
无论是MyBatis在预处理语句中设置一个参数,还是从结果集中取出一个值时,类型处理器被用来将获取的值以合适的方式转换成Java类型。
你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。要这样做的话,简单实现TypeHandler接口(org.mybatis.type),然后映射新的类型处理器类到Java类型,还有可选的一个JDBC类型。
- // ExampleTypeHandler.java
- public class ExampleTypeHandler implements TypeHandler {
- public void setParameter(PreparedStatement ps, int i, Object parameter,JdbcType jdbcType) throws SQLException {
- ps.setString(i, (String) parameter);
- }
- public Object getResult(ResultSet rs, String columnName) throws SQLException {
- return rs.getString(columnName);
- }
- public Object getResult(CallableStatement cs, int columnIndex) throws SQLException {
- return cs.getString(columnIndex);
- }
- }
- // MapperConfig.xml
- <typeHandlers>
- <typeHandler javaType="String" jdbcType="VARCHAR"
- handler="org.mybatis.example.ExampleTypeHandler"/>
- </typeHandlers>
objectFactory
MyBatis每次创建结果对象新的实例时,它使用一个ObjectFactory实例来完成。如果参数映射存在,默认的ObjectFactory不比使用默认构造方法或带参数的构造方法实例化目标类做的工作多。如果你想重写默认的ObjectFactory,你可以创建你自己的。
- // ExampleObjectFactory.java
- public class ExampleObjectFactory extends DefaultObjectFactory {
- public Object create(Class type) {
- return super.create(type);
- }
- public Object create(Class type,List<Class> constructorArgTypes,List<Object> constructorArgs) {
- return super.create(type, constructorArgTypes, constructorArgs);
- }
- public void setProperties(Properties properties) {
- super.setProperties(properties);
- }
- }
- // MapperConfig.xml
- <objectFactory type="org.mybatis.example.ExampleObjectFactory">
- <property name="someProperty" value="100"/>
- </objectFactory>
plugins
MyBatis允许你在某一点拦截已映射语句执行的调用。默认情况下,MyBatis允许使用插件来拦截方法调用:
Executor
(update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
ParameterHandler
(getParameterObject, setParameters)
ResultSetHandler
(handleResultSets, handleOutputParameters)
StatementHandler
(prepare, parameterize, batch, update, query)
如果你尝试修改或覆盖一个给定的方法,你可能会打破MyBatis的核心。这是低层次的类和方法,要谨慎使用插件。
使用插件是它们提供的非常简单的力量。简单实现拦截器接口,要确定你想拦截的指定签名。
- // ExamplePlugin.java
- @Intercepts({@Signature(type= Executor.class,method = "update",args = {MappedStatement.class,Object.class})})
- public class ExamplePlugin implements Interceptor {
- public Object intercept(Invocation invocation) throws Throwable{
- return invocation.proceed();
- }
- public Object plugin(Object target) {
- return Plugin.wrap(target, this);
- }
- public void setProperties(Properties properties) {
- }
- }
- // MapperConfig.xml
- <plugins>
- <plugin interceptor="org.mybatis.example.ExamplePlugin">
- <property name="someProperty" value="100"/>
- </plugin>
- </plugins>
environments
MyBatis可以配置多种环境。这会帮助你将SQL映射应用于多种数据库之中。
要记得一个很重要的问题:你可以配置多种环境,但你只能为每个SqlSessionFactory实例选择一个。所以,如果你想连接两个数据库,你需要创建两个SqlSessionFactory实例,每个数据库对应一个。而如果是三个数据库,你就需要三个实例,以此类推。
每个数据库对应一个SqlSessionFactory
为了明确创建哪种环境,你可以将它作为可选的参数传递给SqlSessionFactoryBuilder。可以接受环境配置的两个方法签名是:
- SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment);
- SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment,properties);
- SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader);
- SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader,properties);
- <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>
(1)默认的环境ID(比如:default=”development”)。
(2)每个environment元素定义的环境ID(比如:id=”development”)。
(3)事务管理器的配置(比如:type=”JDBC”)。
(4)数据源的配置(比如:type=”POOLED”)。
默认的环境和环境ID是自我解释的。你可以使用你喜欢的名称来命名,只要确定默认的要匹配其中之一。
transactionManager
在MyBatis中有两种事务管理器类型(也就是type=”[JDBC|MANAGED]”):
(1) JDBC – 这个配置直接简单使用了JDBC的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围。
(2) MANAGED – 这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期(比如Spring或JEE应用服务器的上下文)。
默认情况下它会关闭连接。然而一些容器并不希望这样,因此如果你需要从连接中停止它,将closeConnection属性设置为false。例如:
- <transactionManager type="MANAGED">
- <property name="closeConnection" value="false"/>
- </transactionManager>
dataSource
dataSource元素使用基本的JDBC数据源接口来配置JDBC连接对象的资源。
有三种内建的数据源类型(也就是type=”???”):
(1)UNPOOLED – 这个数据源的实现是每次被请求时简单打开和关闭连接。
UNPOOLED类型的数据源仅仅用来配置以下5种属性:
driver – 这是JDBC驱动的Java类的完全限定名(如果你的驱动包含的有,它也不是数据源类)。
url – 这是数据库的JDBC URL地址。
username – 登录数据库的用户名。
password – 登录数据库的密码。
defaultTransactionIsolationLevel – 默认的连接事务隔离级别。
作为可选项,你可以传递数据库驱动的属性。要这样做,属性的前缀是以“driver.”开头的,例如:
driver.encoding=UTF8
这样就会传递以值“UTF8”来传递 “encoding” 属性,它是通过DriverManager.getConnection(url,driverProperties)方法传递给数据库驱动。
(2)POOLED – 这是JDBC连接对象的数据源连接池的实现,用来避免创建新的连接实例时必要的初始连接和认证时间。这是一种当前Web应用程序用来快速响应请求很流行的方法。
除了上述(UNPOOLED)的属性之外,还有很多属性可以用来配置POOLED数据源:
poolMaximumActiveConnections – 在任意时间存在的活动(也就是正在使用)连接的数量。默认值:10
poolMaximumIdleConnections – 任意时间存在的空闲连接数。
poolMaximumCheckoutTime – 在被强制返回之前,池中连接被检查的时间。默认值:20000毫秒(也就是20秒)
poolTimeToWait – 这是给连接池一个打印日志状态机会的低层次设置,还有重新尝试获得连接,这些情况下往往需要很长时间(为了避免连接池没有配置时静默失败)。
默认值:20000毫秒(也就是20秒)
poolPingQuery – 发送到数据的侦测查询,用来验证连接是否正常工作,并且准备接受请求。
默认是“NO PING QUERY SET”,这会引起许多数据库驱动连接由一个错误信息而导致失败。
poolPingEnabled – 这是开启或禁用侦测查询。如果开启,你必须用一个合法的SQL语句(最好是很快速的)设置poolPingQuery属性。默认值:false。
poolPingConnectionsNotUsedFor – 这是用来配置poolPingQuery多次时间被用一次。这可以被设置匹配标准的数据库连接超时时间,来避免不必要的侦测。
默认值:0(也就是所有连接每一时刻都被侦测-但仅仅当poolPingEnabled为true时适用)。
JNDI – 这个数据源的实现是为了使用如Spring或应用服务器这类的容器,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。
这个数据源配置只需要两个属性:
initial_context – 这个属性用来从初始上下文中寻找环境(也就是initialContext.lookup(initial——context))。
这是个可选属性,如果被忽略,那么data_source属性将会直接以initialContext为背景再次寻找。
data_source – 这是引用数据源实例位置的上下文的路径。它会以由initial_context查询返回的环境为背景来查找,
如果initial_context没有返回结果时,直接以初始上下文为环境来查找。
和其他数据源配置相似,它也可以通过名为“env.”的前缀直接向初始上下文发送属性。比如:
env.encoding=UTF8
在初始化之后,这就会以值“UTF8”向初始上下文的构造方法传递名为“encoding”的属性。
mappers
既然MyBatis的行为已经由上述元素配置完了,我们现在就要定义SQL映射语句了。但是,首先我们需要告诉MyBatis到哪里去找到这些语句。Java在这方面没有提供一个很好的方法,所以最佳的方式是告诉MyBatis到哪里去找映射文件。你可以使用相对于类路径的资源引用,或者字符表示,或url引用的完全限定名(包括file:///URLs)。例如:
- // 使用相对于类路径的资源
- <mappers>
- <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
- <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
- <mapper resource="org/mybatis/builder/PostMapper.xml"/>
- </mappers>
- // 使用完全限定路径
- <mappers>
- <mapper url="file:///var/sqlmaps/AuthorMapper.xml"/>
- <mapper url="file:///var/sqlmaps/BlogMapper.xml"/>
- <mapper url="file:///var/sqlmaps/PostMapper.xml"/>
- </mappers>