MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
在 MyBatis 中,数据源(DataSource)是一个非常重要的组件,它负责管理与数据库的连接。本文将深入探讨 MyBatis3 是如何获取数据源的。
在 MyBatis 的配置文件中,数据源是通过 <dataSource>
标签来配置的。MyBatis 支持多种类型的数据源,包括 UNPOOLED、POOLED 和 JNDI。以下是一个典型的配置示例:
<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"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
在这个配置中,<dataSource>
标签的 type
属性指定了数据源的类型,POOLED
表示使用连接池的数据源。<property>
子标签则用于配置数据源的具体参数,如数据库驱动、连接 URL、用户名和密码等。
MyBatis 在启动时会解析配置文件,并根据配置创建相应的数据源。数据源的创建过程主要发生在 org.apache.ibatis.session.Configuration
类中。具体来说,Configuration
类会调用 org.apache.ibatis.datasource.DataSourceFactory
接口的实现类来创建数据源。
DataSourceFactory
接口有两个主要的实现类:UnpooledDataSourceFactory
和 PooledDataSourceFactory
。这两个类分别用于创建非池化和池化的数据源。
UnpooledDataSourceFactory
用于创建非池化的数据源。它的实现非常简单,主要是在 setProperties
方法中设置数据源的属性,并在 getDataSource
方法中返回一个 UnpooledDataSource
实例。
public class UnpooledDataSourceFactory implements DataSourceFactory {
private UnpooledDataSource dataSource;
public UnpooledDataSourceFactory() {
this.dataSource = new UnpooledDataSource();
}
@Override
public void setProperties(Properties properties) {
// 设置数据源属性
}
@Override
public DataSource getDataSource() {
return dataSource;
}
}
PooledDataSourceFactory
用于创建池化的数据源。它的实现与 UnpooledDataSourceFactory
类似,只是在 getDataSource
方法中返回一个 PooledDataSource
实例。
public class PooledDataSourceFactory extends UnpooledDataSourceFactory {
public PooledDataSourceFactory() {
this.dataSource = new PooledDataSource();
}
}
在 MyBatis 中,数据源的获取主要通过 org.apache.ibatis.session.SqlSessionFactory
接口的实现类 org.apache.ibatis.session.defaults.DefaultSqlSessionFactory
来完成。DefaultSqlSessionFactory
在初始化时会从 Configuration
对象中获取数据源,并将其保存在 environment
属性中。
public class DefaultSqlSessionFactory implements SqlSessionFactory {
private final Configuration configuration;
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}
@Override
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
}
在 openSessionFromDataSource
方法中,environment.getDataSource()
方法用于获取数据源。environment
是 Configuration
对象中的一个属性,它包含了数据源、事务工厂等信息。
在 MyBatis 中,数据源主要用于获取数据库连接。当执行 SQL 语句时,MyBatis 会从数据源中获取一个连接,并在执行完毕后将连接返回到连接池中(如果使用的是池化的数据源)。
public class SimpleExecutor extends BaseExecutor {
@Override
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
Statement stmt = null;
try {
Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
stmt = prepareStatement(handler, ms.getStatementLog());
return handler.<E>query(stmt, resultHandler);
} finally {
closeStatement(stmt);
}
}
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
Statement stmt;
Connection connection = getConnection(statementLog);
stmt = handler.prepare(connection, transaction.getTimeout());
handler.parameterize(stmt);
return stmt;
}
protected Connection getConnection(Log statementLog) throws SQLException {
Connection connection = transaction.getConnection();
if (statementLog.isDebugEnabled()) {
return ConnectionLogger.newInstance(connection, statementLog, queryStack);
} else {
return connection;
}
}
}
在 SimpleExecutor
类的 doQuery
方法中,getConnection
方法用于从事务对象中获取数据库连接。事务对象在初始化时会从数据源中获取连接。
MyBatis3 中数据源的获取过程主要分为配置、创建、获取和使用四个步骤。通过配置文件,我们可以指定数据源的类型和参数。MyBatis 在启动时会根据配置创建相应的数据源,并将其保存在 Configuration
对象中。在执行 SQL 语句时,MyBatis 会从数据源中获取数据库连接,并在执行完毕后将连接返回到连接池中。
通过本文的分析,我们可以更好地理解 MyBatis3 中数据源的获取机制,这对于我们深入理解 MyBatis 的工作原理以及进行性能优化都具有重要的意义。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。