Abstract
MyBatis 应用程序主要都是使用SqlSessionFactory实例的,一个 SqlSessionFactory 实例可以通过SqlSessionFactoryBuilder 获得。
SqlSessionFactoryBuilder 可以从一个 mybatis-config.xml 配置文件或者一个预定义的配置类的实例获得。
mybatis-config.xml 就是用于生成 SqlSessionFactory 实例的配置文件。
MyBatis 核心配置文件 mybatis-config.xml 中,大标签 configuration 下子标签包括:
configuration 配置
|--- properties 属性
|--- settings 设置
|--- typeAliases 类型命名
|--- typeHandlers 类型处理器
|--- objectFactory 对象工厂
|--- plugins 插件
|--- environments 环境
| |--- environment 环境变量
| |--- transactionManager 事务管理器
| |--- dataSource 数据源
|--- databaseIdProvider 数据库厂商标识
|--- mappers 映射器
注:
实际中,当MyBatis和诸如Spring等框架一起使用时,一些配置写在别的框架配置文件中。
现介绍各个标签的使用。
properties
存放数据库连接信息可以直接书写,如下这种方式
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mappers/UserMapper.xml"/>
</mappers>
</configuration>
但是更常见的做法是,将数据库连接信息存放在properties资源文件中。
- 创建资源文件jdbc.properties
jdbc.driverClassName=ocom.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_demo
jdbc.username=root
jdbc.password=
- 在mybatis-config.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>
<properties resource="jdbc.properties" />
<mappers>
<mapper resource="mappers/UserMapper.xml"/>
</mappers>
</configuration>
当然也可以在properties标签中定义属性
<properties resource="jdbc.properties">
<property name="jdbc.driverClassName" value="com.mysql.jdbc.Driver"/>
</properties>
- 使用properties文件里的属性
<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>
注:配置的加载顺序为
- 在 properties 元素体内指定的属性首先被读取。
- 从类路径下资源或 properties 元素的 url 属性中加载的属性第二被读取,它会覆盖已经存在的完全一样的属性。
- 作为方法参数传递的属性最后被读取,它也会覆盖任一已经存在的完全一样的属性,这些属性可能是从 properties 元素体内和资源/url 属性中加载的。
因此,属性的优先级为:方法直接传递参数 > 通过resource、url引用的资源 > properties元素体内定义
settings
设置MyBatis运行时的参数。
<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="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>
具体参数含义请查阅http://www.mybatis.org/mybatis-3/zh/configuration.html#settings
typeAliases
作用是给Java类型取一个别名,方便在核心配置、映射配置中来使用这个Java类型。
例如原先UserMapper.xml的写法是
<mapper namespace="UserMapper">
<select id="queryUser" resultType="com.ggli.entity.User">
SELECT * FROM t_user
</select>
</mapper>
而用typeAliases来进行别名配置后的写法是
<typeAliases>
<typeAlias type="com.ggli.entity.User" alias="User"/>
</typeAliases>
<mapper namespace="UserMapper">
<select id="queryUser" resultType="User">
SELECT * FROM t_user
</select>
</mapper>
除此之外,MyBatis还有许多内建类型别名供用户使用,在此不一一举例。
typeHandlers
类型处理器的作用是
- 获取数据库的值,以合适的方式转变为对应的Java类型
- 将Java类型,以合适的方式转化为数据库的保存类型
MyBatis中默认的类型处理器请参阅http://www.mybatis.org/mybatis-3/zh/configuration.html#typeHandlers
可以自定义类型处理器来处理不支持的或非标准的类型。具体做法为:实现 org.apache.ibatis.type.TypeHandler接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler,然后可以选择性地将它映射到一个 JDBC 类型。
objectFactory
每次MyBatis 为结果对象创建一个新实例,都会用到对象工厂(ObjectFactory)。
如果你重写objectFactory的默认操作,你可以通过继承 org.apache.ibatis.reflection.factory.DefaultObjectFactory 创建自定义操作。
编写一个类实现 DefaultObjectFactory,覆盖3个方法。
public class MyObjectFactory 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);
}
}
最后在mybatis-config.xml 中加上 objectFactory 标签。
<objectFactory type="com.ggli.factory.MyObjectFatory">
<property name="prop" value="val"/>
</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 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定了想要拦截的方法签名即可。
// MyPlugin.java
@Intercepts({@Signature(
type = Executor.class,
method = "update",
args = {MappedStatement.class,Object.class})})
public class MyPlugin 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) {
}
}
<!-- mybatis-config.xml -->
<plugins>
<plugin interceptor="com.ggli.plugins.MyPlugin">
<property name="prop" value="100"/>
</plugin>
</plugins>
上面的插件将会拦截在 Executor 实例中所有的 “update” 方法调用, 这里的 Executor 是负责执行低层映射语句的内部对象。
注:
除了用插件来修改 MyBatis 核心行为之外,还可以通过完全覆盖配置类来达到目的。只需继承后覆盖其中的每个方法,再把它传递到 sqlSessionFactoryBuilder.build(myConfig) 方法即可。
environments
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者共享相同 Schema 的多个生产数据库, 想使用相同的 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="production">
<environment id="production">
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</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>
事务管理器(transactionManager)
在 MyBatis 中有两种类型的事务管理器,即 type="[JDBC|MANAGED]":
注:
如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器, 因为 Spring 模块会使用自带的管理器来覆盖前面的配置。
数据源(dataSource)
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。有三种内建的数据源类型,即 type="[UNPOOLED|POOLED|JNDI]"
- UNPOOLED
这个数据源的实现只是每次被请求时打开和关闭连接,它对在及时可用连接方面没有性能要求的简单应用程序是一个很好的选择。它需要配置5中属性
driver – 这是 JDBC 驱动的 Java 类的完全限定名(并不是JDBC驱动中可能包含的数据源类)。
url – 这是数据库的 JDBC URL 地址。
username – 登录数据库的用户名。
password – 登录数据库的密码。
defaultTransactionIsolationLevel – 默认的连接事务隔离级别。
作为可选项,你也可以传递属性给数据库驱动。要这样做,属性的前缀为“driver.”,例如:
driver.encoding=UTF8
- POOLED
这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这是一种使得并发 Web 应用快速响应请求的流行处理方式。
除了上述提到 UNPOOLED 下的属性外,会有更多属性用来配置 POOLED 的数据源:
poolMaximumActiveConnections
poolMaximumIdleConnections
poolMaximumCheckoutTime
poolTimeToWait
poolPingQuery
poolPingEnabled
poolPingConnectionsNotUsedFor
第三方数据源
需要实现接口 org.apache.ibatis.datasource.DataSourceFactory, 也可使用任何第三方数据源:
public interface DataSourceFactory {
void setProperties(Properties props);
DataSource getDataSource();
}
org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory 可被用作父类来构建新的数据源适配器,比如下面这段插入 C3P0 数据源所必需的代码:
import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3P0DataSourceFactory extends UnpooledDataSourceFactory {
public C3P0DataSourceFactory() {
this.dataSource = new ComboPooledDataSource();
}
}
在配置中使用该数据源
<dataSource type="com.ggli.C3P0DataSourceFactory">
<property name="driver" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql:mydb"/>
<property name="username" value="postgres"/>
<property name="password" value="root"/>
</dataSource>
databaseIdProvider
MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。
mappers
既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要定义 SQL 映射语句了。但是首先我们需要告诉 MyBatis 到哪里去找到这些语句。 Java 在自动查找这方面没有提供一个很好的方法,所以最佳的方式是告诉 MyBatis 到哪里去找映射文件。你可以使用相对于类路径的资源引用, 或完全限定资源定位符(包括 file:/// 的 URL),或类名和包名等。例如:
- 直接引用定义好的 xml 文件
<!-- Using classpath relative resources -->
<mappers>
<mapper resource="mappers/UserMapper.xml"/>
<mapper resource="com/ggli/builder/AuthorMapper.xml"/>
<mapper resource="com/ggli/builder/PostMapper.xml"/>
</mappers>
- 通过绝对路径引用,注意在绝对路径前加上:
file:///
<!-- Using url fully qualified paths -->
<mappers>
<mapper url="file:///C:/Users/John/IdeaProjects/mybatis-basic/src/main/resources/mappers/UserMapper.xml"/>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
- 引用mapper接口对象的方式
<!-- Using mapper interface classes -->
<mappers>
<mapper class="com.ggli.mapper.UserMapper"/>
<mapper class="com.ggli.builder.AuthorMapper"/>
<mapper class="com.ggli.builder.PostMapper"/>
</mappers>
- 引用mapper接口包的方式:
<!-- Register all interfaces in a package as mappers -->
<mappers>
<package name="com.ggli.mapper"/>
<package name="com.ggli.builder"/>
</mappers>
这些配置会告诉了 MyBatis 去哪里找映射文件,剩下的细节就应该是每个 SQL 映射文件了。
4389

被折叠的 条评论
为什么被折叠?



