最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解MyBatis的SqlSession獲取流程

 更新時間:2023年07月10日 10:15:58   作者:半夏之沫  
SqlSession的獲取是通過SqlSessionFactory的openSession() 方法,那么具體的獲取流程是什么,所以本文就給大家詳細講解一下MyBatis的SqlSession獲取流程,需要的朋友可以參考下

前言

已知在MyBatis的使用中,使用MyBatis時會先讀取配置文件mybatis-config.xml為字符流或者字節(jié)流,然后通過SqlSessionFactoryBuilder基于配置文件的字符流或字節(jié)流來構(gòu)建SqlSessionFactory,然后再通過SqlSessionFactoryopenSession() 方法獲取SqlSession,示例代碼如下所示。

public static void main(String[] args) throws Exception {
    String resource = "mybatis-config.xml";
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
            .build(Resources.getResourceAsStream(resource));
    SqlSession sqlSession = sqlSessionFactory.openSession();
}

上述示例代碼中的SqlSessionFactory實際為DefaultSqlSessionFactory,本篇文章將對DefaultSqlSessionFactory獲取SqlSession的流程進行學習。

正文

DefaultSqlSessionFactoryopenSession() 方法如下所示。

public SqlSession openSession() {
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}

繼續(xù)看openSessionFromDataSource() 方法的實現(xiàn),如下所示。

private SqlSession openSessionFromDataSource(ExecutorType execType, 
                                             TransactionIsolationLevel level, 
                                             boolean autoCommit) {
    Transaction tx = null;
    try {
        // Environment中包含有事務工廠和數(shù)據(jù)源
        final Environment environment = configuration.getEnvironment();
        // 獲取事務工廠
        // 如果配置了JDBC事務,則獲取JDBC事務工廠,否則獲取MANAGED事務工廠
        final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
        // 創(chuàng)建事務
        tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
        // 創(chuàng)建執(zhí)行器
        final Executor executor = configuration.newExecutor(tx, execType);
        // 構(gòu)建DefaultSqlSession并返回
        return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
        closeTransaction(tx);
        throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
        ErrorContext.instance().reset();
    }
}

openSessionFromDataSource() 方法會先從Configuration中將Environment獲取出來,Environment中包含有事務工廠和數(shù)據(jù)源,Environment是在MyBatis配置文件中進行配置并會在加載MyBatis配置文件時被添加到Configuration中。

MyBatis的配置文件中可以配置兩種事務工廠,為JDBC事務工廠和MANAGED事務工廠,它們分別可以創(chuàng)建JDBC事務和MANAGED事務,類圖如下所示。

獲取事務工廠的getTransactionFactoryFromEnvironment() 方法如下所示。

private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
    if (environment == null || environment.getTransactionFactory() == null) {
        // 配置了事務工廠則使用配置的事務工廠
        // MyBatis可以配置JDBC和MANAGED這兩種事務工廠
        return new ManagedTransactionFactory();
    }
    // 沒做配置的情況下使用MANAGED事務工廠
    return environment.getTransactionFactory();
}

MyBatis中如果使用JDBC事務,則事務的管理由java.sql.Connection完成,如果使用MANAGED事務,則MyBatis會將事務的管理交由WEB容器(Tomcat,JBoss等)來完成。以commit()rollback() 方法為例,看下JdbcTransactionManagedTransaction對這兩個方法的實現(xiàn),如下所示。

public class JdbcTransaction implements Transaction {
    // ......
    @Override
    public void commit() throws SQLException {
        if (connection != null && !connection.getAutoCommit()) {
            if (log.isDebugEnabled()) {
                log.debug("Committing JDBC Connection [" + connection + "]");
            }
            connection.commit();
        }
    }
    @Override
    public void rollback() throws SQLException {
        if (connection != null && !connection.getAutoCommit()) {
            if (log.isDebugEnabled()) {
                log.debug("Rolling back JDBC Connection [" + connection + "]");
            }
            connection.rollback();
        }
    }
    // ......
}
public class ManagedTransaction implements Transaction {
    // ......
    @Override
    public void commit() throws SQLException {
        // 不做任何事情
    }
    @Override
    public void rollback() throws SQLException {
        // 不做任何事情
    }
    // ......
}

回到openSessionFromDataSource() 方法,創(chuàng)建好事務后,會構(gòu)建執(zhí)行器Executor,看一下newExecutor(Transaction transaction, ExecutorType executorType) 方法的實現(xiàn),如下所示。

public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    // 根據(jù)ExecutorType的枚舉值創(chuàng)建對應類型的Executor
    if (ExecutorType.BATCH == executorType) {
        executor = new BatchExecutor(this, transaction);
    } else if (ExecutorType.REUSE == executorType) {
        executor = new ReuseExecutor(this, transaction);
    } else {
        executor = new SimpleExecutor(this, transaction);
    }
    // 如果MyBatis配置文件中開啟了二級緩存
    if (cacheEnabled) {
        // 創(chuàng)建CachingExecutor作為Executor的裝飾器,為Executor增加二級緩存功能
        executor = new CachingExecutor(executor);
    }
    // 將插件邏輯添加到Executor中
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
}

在上面構(gòu)建執(zhí)行器Executor的方法中,主要是做了三件事情,解釋如下。

第一件事情,根據(jù)ExecutorType的枚舉值創(chuàng)建對應類型的ExecutorExecutorType枚舉值如下所示。

public enum ExecutorType {
    SIMPLE, REUSE, BATCH
}

MyBatis提供了三種類型的Executor,分別為BatchExecutor,ReuseExecutorSimpleExecutor,類圖如下所示。

BaseExecutor中定義了四個抽象方法,如下所示。

protected abstract int doUpdate(MappedStatement ms, Object parameter) throws SQLException;
protected abstract List<BatchResult> doFlushStatements(boolean isRollback) throws SQLException;
protected abstract <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
    throws SQLException;
protected abstract <E> Cursor<E> doQueryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds, BoundSql boundSql)
    throws SQLException;

BaseExecutor提供的方法中會調(diào)用這四個抽象方法,同時這四個抽象方法需要由BatchExecutor,ReuseExecutorSimpleExecutor根據(jù)各自的功能進行實現(xiàn),所以Executor的設(shè)計使用了模板設(shè)計模式。

第二件事情,如果在MyBatis配置文件中開啟了二級緩存,則為Executor創(chuàng)建裝飾器CachingExecutor,以增加對二級緩存功能的支持。CachingExecutorExecutor的關(guān)系如下所示。

CachingExecutor實現(xiàn)了Executor接口,同時CachingExecutor持有Executor的引用,這是裝飾器模式的應用。關(guān)于MyBatis中的緩存,會在后續(xù)的文章中進行介紹。

第三件事情,如果配置了插件,則將插件的邏輯添加到Executor中。關(guān)于MyBatis中的插件,會在后續(xù)的文章中進行介紹。

回到openSessionFromDataSource() 方法,創(chuàng)建好Executor后,就會調(diào)用DefaultSqlSession的構(gòu)造方法創(chuàng)建一個DefaultSqlSession并返回,在DefaultSqlSession的構(gòu)造方法中只是進行了簡單的賦值,如下所示。

public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
    this.configuration = configuration;
    this.executor = executor;
    this.dirty = false;
    this.autoCommit = autoCommit;
}

至此,SqlSession就創(chuàng)建出來了。

總結(jié)

SqlSession的獲取是通過SqlSessionFactoryopenSession() 方法,SqlSession的創(chuàng)建過程主要先是創(chuàng)建事務管理器,然后基于事務管理器創(chuàng)建執(zhí)行器Executor,最后基于Executor創(chuàng)建SqlSession。

通常,SqlSessionFactoryDefaultSqlSessionFactory,創(chuàng)建出來的SqlSessionDefaultSqlSession

整體的一個流程圖如下所示。

以上就是詳解MyBatis的SqlSession獲取流程的詳細內(nèi)容,更多關(guān)于MyBatis SqlSession獲取流程的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • spring cloud內(nèi)容匯總(各個功能模塊、啟動、部署)的詳細過程

    spring cloud內(nèi)容匯總(各個功能模塊、啟動、部署)的詳細過程

    Spring Cloud 是一套基于 Spring Boot 的框架集合,用于構(gòu)建分布式微服務架構(gòu),文章介紹了Spring Cloud框架及其相關(guān)工具的使用,還詳細介紹了如何配置和使用這些功能,包括配置文件、依賴管理以及實際應用示例,感興趣的朋友一起看看吧
    2024-11-11
  • Java實現(xiàn)發(fā)送短信驗證碼+redis限制發(fā)送的次數(shù)功能

    Java實現(xiàn)發(fā)送短信驗證碼+redis限制發(fā)送的次數(shù)功能

    這篇文章主要介紹了Java實現(xiàn)發(fā)送短信驗證碼+redis限制發(fā)送的次數(shù),本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • SpringCloud Netfilx Ribbon負載均衡工具使用方法介紹

    SpringCloud Netfilx Ribbon負載均衡工具使用方法介紹

    Ribbon是Netflix的組件之一,負責注冊中心的負載均衡,有助于控制HTTP和TCP客戶端行為。Spring Cloud Netflix Ribbon一般配合Ribbon進行使用,利用在Eureka中讀取的服務信息,在調(diào)用服務節(jié)點時合理進行負載
    2022-12-12
  • 深入了解Java.Util.Date詳情

    深入了解Java.Util.Date詳情

    這篇文章主要介紹了Java.Util.Date,很少有類能像java.util.Date那樣在堆棧溢出方面引起如此多的類似問題,關(guān)于具體原因下文內(nèi)容詳細介紹,需要的朋友可以參考一下
    2022-06-06
  • Java中在時間戳計算的過程中遇到的數(shù)據(jù)溢出問題解決

    Java中在時間戳計算的過程中遇到的數(shù)據(jù)溢出問題解決

    這篇文章主要介紹了Java中在時間戳計算的過程中遇到的數(shù)據(jù)溢出問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-06-06
  • 我對@RestController注解的理解

    我對@RestController注解的理解

    這篇文章主要介紹了我對@RestController注解的理解,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • MyBatis實戰(zhàn)指南之MyBatis日志詳解

    MyBatis實戰(zhàn)指南之MyBatis日志詳解

    本文系統(tǒng)講解MyBatis日志模塊,涵蓋日志作用、框架選擇(SLF4J/Log4j等)、配置方法、源碼解析及日志級別控制,幫助開發(fā)者掌握調(diào)試技巧與性能優(yōu)化實踐,感興趣的朋友跟隨小編一起看看吧
    2025-07-07
  • IDEA下因Lombok插件產(chǎn)生的Library source does not match the bytecode報錯問題及解決方法(親測可用)

    IDEA下因Lombok插件產(chǎn)生的Library source does not match the bytecode報

    這篇文章主要介紹了IDEA下因Lombok插件產(chǎn)生的Library source does not match the bytecode報錯問題及解決方法,親測試過好用,需要的朋友可以參考下
    2020-04-04
  • SpringMVC日期類型接收空值異常問題解決方法

    SpringMVC日期類型接收空值異常問題解決方法

    這篇文章主要介紹了SpringMVC日期類型接收空值異常問題解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • springboot結(jié)合mybatis操作事務配置的處理

    springboot結(jié)合mybatis操作事務配置的處理

    在操作數(shù)據(jù)庫的時候,經(jīng)常會使用事務的處理,本文主要介紹了springboot結(jié)合mybatis操作事務配置的處理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-07-07

最新評論

三河市| 河南省| 绥江县| 明溪县| 广东省| 周至县| 西昌市| 三亚市| 北辰区| 河间市| 汉沽区| 墨江| 新闻| 库车县| 中超| 嘉鱼县| 潼南县| 文山县| 保靖县| 武陟县| 凌源市| 清苑县| 轮台县| 汝南县| 临潭县| 安化县| 石家庄市| 澄迈县| 罗定市| 海城市| 怀柔区| 会宁县| 哈巴河县| 疏勒县| 澜沧| 宣武区| 大冶市| 陆河县| 伊吾县| 沙雅县| 永仁县|