温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

MyBatis3源码解析之怎么获取数据源

发布时间:2022-09-19 17:33:22 阅读:167 作者:iii 栏目:开发技术
开发者测试专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

MyBatis3源码解析之怎么获取数据源

MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

在 MyBatis 中,数据源(DataSource)是一个非常重要的组件,它负责管理与数据库的连接。本文将深入探讨 MyBatis3 是如何获取数据源的。

1. 数据源的配置

在 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、用户名和密码等。

2. 数据源的创建

MyBatis 在启动时会解析配置文件,并根据配置创建相应的数据源。数据源的创建过程主要发生在 org.apache.ibatis.session.Configuration 类中。具体来说,Configuration 类会调用 org.apache.ibatis.datasource.DataSourceFactory 接口的实现类来创建数据源。

DataSourceFactory 接口有两个主要的实现类:UnpooledDataSourceFactoryPooledDataSourceFactory。这两个类分别用于创建非池化和池化的数据源。

2.1 UnpooledDataSourceFactory

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;
  }
}

2.2 PooledDataSourceFactory

PooledDataSourceFactory 用于创建池化的数据源。它的实现与 UnpooledDataSourceFactory 类似,只是在 getDataSource 方法中返回一个 PooledDataSource 实例。

public class PooledDataSourceFactory extends UnpooledDataSourceFactory {

  public PooledDataSourceFactory() {
    this.dataSource = new PooledDataSource();
  }
}

3. 数据源的获取

在 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() 方法用于获取数据源。environmentConfiguration 对象中的一个属性,它包含了数据源、事务工厂等信息。

4. 数据源的使用

在 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 方法用于从事务对象中获取数据库连接。事务对象在初始化时会从数据源中获取连接。

5. 总结

MyBatis3 中数据源的获取过程主要分为配置、创建、获取和使用四个步骤。通过配置文件,我们可以指定数据源的类型和参数。MyBatis 在启动时会根据配置创建相应的数据源,并将其保存在 Configuration 对象中。在执行 SQL 语句时,MyBatis 会从数据源中获取数据库连接,并在执行完毕后将连接返回到连接池中。

通过本文的分析,我们可以更好地理解 MyBatis3 中数据源的获取机制,这对于我们深入理解 MyBatis 的工作原理以及进行性能优化都具有重要的意义。

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI

开发者交流群×