MyBatis之配置文件解析_环境environments的作用及处理
环境对象
Environment对象 环境对象是一个类,提供联接数据库的环境,mybatis支持多环境开发,可配置多个环境,根据环境不同,使用其中的一个。Confguration对象持有一个Environment对象,构建Configuration时,可以传入环境id,即使用指定的环境配置,或者使用默认的配置。Environment持有一个TransactionFactory及DataSource对象,环境对象通过解析XML配置文件的元素environments来构建。
public final class Environment {
// 环境id,不同的id表示不同的环境
private final String id;
// 创建事务的工厂
private final TransactionFactory transactionFactory;
// 数据源对象, java.sql.DataSource
private final DataSource dataSource;
// 可以通过构造方法创建Envionment对象
// 也可通过静态内部类Builder来构建
public static class Builder {}
}
配置文件中环境的配置
配置文件中环境的配置主要指与数据库联接的配置,mybatis支持多环境的配置。enviomnents下可配置多个enviroment,若指定了所使用的id,则就使用这个id的environment,否则使用的id为environments属性default指定的environment。
<!-- mybatis环境相关配置 -->
<environments default="development">
<environment id="development">
<!-- 事务工厂的类型, JDBC是mybatis提供的 -->
<transactionManager type="JDBC"/>
<!-- 数据源类型, POOLED是mybatis提供的,配置的类型是DataSourceFactory -->
<dataSource type="POOLED">
<!-- 这种形式的配置,解析时转换为Properties对象, 创建DataSource对象,可以用这里的name-value,设置属性值 -->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${uname}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
<!-- 可以配置多个环境 -->
</environments>
environments标签的解析
XMLConfigBuilder的方法environmentsElement用来解析environments标签,构造好Environment对象,并保存在Configuration对象。解析时,若SqlSessionFactoryBuilder在创建XMLConfigBuilder对象时传入一个字符串environment,则这个字符串对应着标签environment的id属性,若没有传入则使用environments标签的default属性值作为environment字符串的值,用这个字符串匹配标签environment的id属性,匹配到则使用这个environment标签的配置创建Environment对象。
// 解析environments标签
private void environmentsElement(XNode context) throws Exception {
if (context != null) {
// environment是构造XMLConfigBuilder对象时外部传入的environment的id,若不空,则就用这个id指定的environment
if (environment == null) {
// 若为null,则使用environment属性default的值作为environment的id
environment = context.getStringAttribute("default");
}
for (XNode child : context.getChildren()) {
String id = child.getStringAttribute("id");
if (isSpecifiedEnvironment(id)) {
// 获得TransactionFactory对象
TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
// 获得DataSourceFactory对象
DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
DataSource dataSource = dsFactory.getDataSource();
// 构造Environment对象
Environment.Builder environmentBuilder = new Environment.Builder(id)
.transactionFactory(txFactory)
.dataSource(dataSource);
// 将Environment对象保存到configuration对象中
configuration.setEnvironment(environmentBuilder.build());
}
}
}
}
TransactionFactory及相关类
TransactionFactory是一个接口,用来构造事务Transaction对象,Transaction是一个用来进行事务处理(提交与回滚)的接口。
public interface TransactionFactory {
default void setProperties(Properties props) {
// NOP
}
Transaction newTransaction(Connection conn);
Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
}
mybatis提供的TransactionFactory的实现类是JdbcTransactionFactory及ManagedTransactionFactory,它们创建的Transaction的对象分别是JdbcTransaction及ManagedTransaction,在Configuration构造方法中注册了JdbcTransactionFactory及ManagedTransactionFactory这两个类型,别名分别为JDBC及MANAGED
public Configuration() {
// mybatis默认注册的TransactionFactory
typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
}
JdbcTransaction代码示例
JdbcTransactionFactory创建的Transaction对象是JdbcTransaction,JdbcTransaction使用Connection对象提交与回滚事务,下面是JdbcTransaction中提交事务的代码
public class JdbcTransaction implements Transaction {
protected Connection connection;
protected DataSource dataSource;
protected TransactionIsolationLevel level;
protected boolean autoCommit;
@Override
public void commit() throws SQLException {
// 使用Connection对象提交事务
if (connection != null && !connection.getAutoCommit()) {
if (log.isDebugEnabled()) {
log.debug("Committing JDBC Connection [" + connection + "]");
}
connection.commit();
}
}
}
TransactionFactory对应的XML配置,在environment的子标签transactionManager中,如下所示
<environment id="development">
<!-- 事务工厂的类型, JDBC是mybatis提供的,对应的实现类是JdbcTransactionFactory -->
<transactionManager type="JDBC"/>
</environment>
transactionManager标签的解析
这个解析很简单,即从type属性中获得TransactionFactory的类型,创建这个对象返回,由Envionment对象使用。
private TransactionFactory transactionManagerElement(XNode context) throws Exception {
// 获得属性type的值,这是一个实现了TransactionFactory的类
if (context != null) {
String type = context.getStringAttribute("type");
Properties props = context.getChildrenAsProperties();
// 获得这个类的对象,并返回,构建环境对象时,使用到这个对象
TransactionFactory factory = (TransactionFactory) resolveClass(type).getDeclaredConstructor().newInstance();
factory.setProperties(props);
return factory;
}
throw new BuilderException("Environment declaration requires a TransactionFactory.");
}
mybatis数据源配置及解析及数据库联接池的实现在下面的文章中介绍。

浙公网安备 33010602011771号