溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MyBatis3源碼解析之怎么獲取數據源

發布時間:2022-09-19 17:33:22 來源:億速云 閱讀:197 作者:iii 欄目:開發技術

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 的工作原理以及進行性能優化都具有重要的意義。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女