MyBatis支持配置多个环境,这有助于将您的SQL映射应用于多个数据库,无论出于何种原因。例如,您可能希望为开发、测试和生产环境使用不同的配置。或者,您可能有多个共享相同模式的生产数据库,并且想要在两者上使用相同的SQL映射。有许多使用情况可以考虑。
有一件重要的事需要记住:虽然您可以配置多个环境,但在每个SqlSessionFactory实例中只能选择一个环境。
因此,如果您想要连接到两个数据库,您需要创建两个SqlSessionFactory实例,每个实例连接一个数据库。对于三个数据库,您需要三个实例,依此类推。这是非常容易记住的。
要指定要构建的环境,只需将其作为可选参数传递给SqlSessionFactoryBuilder。接受环境参数的两种签名是:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);
?如果省略了环境参数,则会加载默认环境,如下所示:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);
environments元素定义了环境的配置。
<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>
请注意以下关键部分:
默认环境和环境ID可以根据您的喜好进行命名,只要确保默认环境与其中一个环境ID匹配即可。
transactionManager
MyBatis包含两种事务管理器类型(即type="[JDBC|MANAGED]"),它们分别是:
<transactionManager type="JDBC">
<property name="skipSetAutoCommitOnClose" value="true"/>
</transactionManager>
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>
?注意:如果您计划将MyBatis与Spring一起使用,就不需要配置任何事务管理器,因为Spring模块会设置自己的事务管理器,覆盖任何先前设置的配置。
这两种事务管理器类型都不需要任何属性。然而,它们都是类型别名,换句话说,您可以使用自己的完全限定类名或类型别名来引用您自己实现的TransactionFactory接口。
public interface TransactionFactory {
default void setProperties(Properties props) { // Since 3.5.2, change to default method
// NOP
}
Transaction newTransaction(Connection conn);
Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
}
?在XML中配置的任何属性都将在实例化后传递给setProperties()方法。您的实现还需要创建一个Transaction实现,它也是一个非常简单的接口:
public interface Transaction {
Connection getConnection() throws SQLException;
void commit() throws SQLException;
void rollback() throws SQLException;
void close() throws SQLException;
Integer getTimeout() throws SQLException;
}
使用这两个接口,您可以完全自定义MyBatis如何处理事务。
dataSource
dataSource元素使用标准的JDBC DataSource接口配置JDBC连接对象的来源。
大多数MyBatis应用程序将按示例配置一个dataSource。但是,这并不是必需的。需要注意的是,为了方便延迟加载(Lazy Loading),这个dataSource是必需的。
有三种内置的数据源类型(type="[UNPOOLED|POOLED|JNDI]"):
UNPOOLED - 这个数据源的实现在每次请求时都会打开和关闭一个连接。虽然速度稍慢,但对于不需要立即可用连接性能的简单应用程序来说,这是一个不错的选择。不同的数据库在这个性能方面也有所不同,所以对于某些数据库来说,池化连接可能不太重要,这种配置会更理想。UNPOOLED数据源有以下属性可以配置:
可选地,您还可以向数据库驱动程序传递属性。要做到这一点,将属性前缀为 ?driver.
?,例如:
driver.encoding=UTF8
这将通过DriverManager.getConnection(url, driverProperties)方法向您的数据库驱动程序传递属性编码,属性名称为encoding,值为UTF8。
POOLED - 这是一种DataSource的实现,它可以池化JDBC连接对象,以避免创建新的连接实例所需的初始连接和身份验证时间。这是并发Web应用程序实现最快响应的常用方法。
除了上述的(UNPOOLED)属性之外,还有许多其他属性可用于配置POOLED数据源。以下是一些常用的属性:
?poolMaximumActiveConnections
?表示同时存在的活动(即正在使用)连接的数量。默认值为10。?poolMaximumIdleConnections
?表示同时存在的空闲连接的数量。?poolMaximumCheckoutTime
?表示一个连接在被"check out"(即被获取)之后可以持续存在的最长时间,超过此时间将被强制返回到连接池。默认值为20000毫秒(即20秒)。?poolTimeToWait
?是一个低级设置,用于在获取连接花费异常长的时间时,给连接池一个机会打印日志状态并重新尝试获取连接(以避免在连接池配置错误的情况下永远静默失败)。默认值为20000毫秒(即20秒)。?poolMaximumLocalBadConnectionTolerance
?是关于线程容忍的坏连接数量的低级设置。如果一个线程获取到一个坏连接,它可能还有另外一次机会重新尝试获取到另一个有效的连接。但重试次数不应超过poolMaximumIdleConnections和poolMaximumLocalBadConnectionTolerance之和。默认值为3(自3.4.5起)。?poolPingQuery
?是发送给数据库的Ping查询,用于验证连接是否工作正常,并准备接受请求。默认值为"NO PING QUERY SET",这会导致大多数数据库驱动程序以良好的错误消息失败。?poolPingEnabled
?用于启用或禁用ping查询。如果启用,还必须设置具有有效SQL语句的poolPingQuery属性(最好是一个非常快的查询)。默认值为false。?poolPingConnectionsNotUsedFor
?配置poolPingQuery的使用频率。可以将其设置为与数据库连接的典型超时时间相匹配,以避免不必要的ping查询。默认值为0(即每次都对所有连接进行ping查询,但前提是poolPingEnabled为true)。?JNDI(Java命名和目录接口)的这种DataSource实现是为与EJB或应用服务器等容器一起使用而设计的。这些容器可以集中或外部地配置DataSource,并将对它的引用放置在JNDI上下文中。这种DataSource配置只需要两个属性:
与其他DataSource配置类似,可以通过在属性前加上"env."的方式将属性直接发送给InitialContext。例如:
env.encoding=UTF8
这将会在实例化InitialContext的构造函数中将属性"encoding"和值"UTF8"发送给InitialContext。
通过实现接口org.apache.ibatis.datasource.DataSourceFactory,您可以插入任何第三方的DataSource:
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();
}
}
?要设置它,为您希望MyBatis调用的每个setter方法添加一个属性。下面是一个连接到PostgreSQL数据库的示例配置:
<dataSource type="org.myproject.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>
?