91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

為何一定要關閉mybatis中的SqlSession

發布時間:2021-12-18 17:59:50 來源:億速云 閱讀:605 作者:柒染 欄目:開發技術

為何一定要關閉mybatis中的SqlSession,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

mybatis的SqlSession一定要關閉

今天在使用mybatis查詢數據時,出現了一個很奇怪的問題。同一條sql語句,查詢時快時慢,并且有一定的規律性,大概每10次查詢中有一次會特別特別的慢,快的只需要1ms,慢的要20000ms,sql代碼及快慢時間截圖如下:

select fknr from jq_fkqk where jjxh = ?

快的情況

為何一定要關閉mybatis中的SqlSession

慢的情況

為何一定要關閉mybatis中的SqlSession

通過日志打印mybatis查詢信息時,我觀察到特別慢的時候,并不是因為它查詢很慢,而是因為它需要等待一段很長的時間才開始:

==> Preparing: select fknr from jq_fkqk where jjxh = ?

說明時間長就出現在這里,這個等待的時間。

為什么會要等待這么久呢?我自然而然的看了一下上一次查詢的函數,發現在函數里面沒有session.close(),把這一句加上,問題就解決了,速度就飛快了。

我本來想查看官方文檔,查看原因,但是沒找到,只能結合我自己的理解來分析一下。SqlSession是通過SqlSessionFactory來構造的,相當于維護一個連接池,當我們不停的進行查詢的時候,由于沒有關閉連接,導致與數據庫的連接數量達到了一個上限(可能連接池有最大連接數,但是我們有找到文檔)。

到達上限之后,再次請求查詢時,Factory說沒有連接了,讓你先等一下,它先去判斷哪些SqlSession已經沒有人使用了(類似于垃圾回收機制),然后調用相應的進程去自動關閉沒用的session連接,注意調用進程可是要排隊的,也要耗時間。

等關閉了沒有用的session之后,Factory通知你,有空閑的session了,開始準備你的查詢吧,所有才會有等待很長一段時間才出現:

==> Preparing: select fknr from jq_fkqk where jjxh = ?

這純屬我自己的理解,但是重點還是表達出來了,就是Mybatis中的session一定要手動去關閉它,session.close(),不然會占著資源,導致性能下降!!!

mybatis中SqlSession使用事項

一.SqlSession的使用范圍

SqlSession中存儲的是編譯好的sql語句,這些sql語句是mybatis配置文件讀取mapper.xml文件生成的,將sql語句存儲到SqlSessionFactory和SqlSession中。封裝了對數據庫的操作,如:查詢、插入、更新、刪除等。

通過SqlSessionFactory創建SqlSession,而SqlSessionFactory是通過SqlSessionFactoryBuilder加載配置文件進行創建。在開發中SqlSession在每次使用完都要進行關閉,使用時創建,也就是多例的,線程安全。SqlSessionFactory在整個類中只有一個對象,也就是單例的,單例的線程不安全。

二.SqlSessionFactoryBuilder

SqlSessionFactoryBuilder用于創建SqlSessionFacoty,SqlSessionFacoty一旦創建完成就不需要SqlSessionFactoryBuilder了,因為SqlSession是通過SqlSessionFactory生產,所以可以將SqlSessionFactoryBuilder當成一個工具類使用,最佳使用范圍是方法范圍即方法體內局部變量。

三.SqlSessionFactory

SqlSessionFactory是一個接口,接口中定義了openSession的不同重載方法,SqlSessionFactory的最佳使用范圍是整個應用運行期間,一旦創建后可以重復使用,通常以單例模式管理SqlSessionFactory。

四.SqlSession

SqlSession是一個面向用戶的接口, sqlSession中定義了數據庫操作,默認使用DefaultSqlSession實現類。

執行過程如下:

1、加載數據源等配置信息

Environment environment = configuration.getEnvironment();

2、創建數據庫鏈接

3、創建事務對象

4、創建Executor,SqlSession所有操作都是通過Executor完成,mybatis源碼如下:

if (ExecutorType.BATCH == executorType) {
      executor = newBatchExecutor(this, transaction);
    } elseif (ExecutorType.REUSE == executorType) {
      executor = new ReuseExecutor(this, transaction);
    } else {
      executor = new SimpleExecutor(this, transaction);
    }
if (cacheEnabled) {
      executor = new CachingExecutor(executor, autoCommit);
    }

SqlSession的實現類即DefaultSqlSession,此對象中對操作數據庫實質上用的是Executor

每個線程都應該有它自己的SqlSession實例。SqlSession的實例不能共享使用,它也是線程不安全的。因此最佳的范圍是請求或方法范圍。絕對不能將SqlSession實例的引用放在一個類的靜態字段或實例字段中。

打開一個 SqlSession;使用完畢就要關閉它。通常把這個關閉操作放到 finally 塊中以確保每次都能執行關閉。如下:

SqlSession session = sqlSessionFactory.openSession();
    try {
          // do work
    } finally {
          session.close();
    }

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

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

AI

和政县| 渭南市| 阿城市| 迭部县| 开远市| 安西县| 湟中县| 蒲江县| 雷州市| 东阿县| 江阴市| 林西县| 香格里拉县| 宁阳县| 东乌珠穆沁旗| 阳曲县| 寻甸| 通山县| 广河县| 保康县| 青河县| 安远县| 黔西县| 玉龙| 怀安县| 湖口县| 色达县| 清原| 娄烦县| 伊吾县| 曲沃县| 凤台县| 乐清市| 平乡县| 观塘区| 合川市| 慈利县| 清水河县| 武强县| 岐山县| 商丘市|