MyBatis--07--啟動過程分析、SqlSession安全問題、攔截器

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔

文章目錄

  • 談談MyBatis的啟動過程
    • 具體的操作過程如下:
    • 實現測試類,并測試
    • SqlSessionFactory
    • SqlSession
  • SqlSession有數據安全問題?
        • 在MyBatis中,==SqlSession是一個線程不安全的對象==
    • 主要原因如下:
    • 如何解決這個問題?
    • Spring整合MyBatis的解決方案
  • 攔截器
    • 1 攔截器的定義
    • 2 攔截器的應用
        • 實際的應用:分頁,SQL檢查。黑白名單。分庫分表等


談談MyBatis的啟動過程

在這里插入圖片描述

在這里插入圖片描述

@Test
public void start() throws Exception{// 1. 加載全局配置文件InputStream in = Resources.getResourceAsStream("mybatis-config.xml");// 2.獲取SqlSessionFactory// DefaultSqlSessionFactorySqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);// 3.獲取SqlSession對象 DefaultSqlSession  Executor--> SimpleExecutor --> CachingExecutor --> 插件的邏輯植入SqlSession sqlSession = factory.openSession();// 4.通過sqlSession的API接口實現數據庫操作List<User> list = sqlSession.selectList("com.bobo.vip.mapper.UserMapper.selectUserById",2);for (User user : list) {System.out.println(user);}// 關閉會話sqlSession.close();
}

具體的操作過程如下:

  1. 加載配置文件:MyBatis的配置文件是一個XML文件,包含了數據庫連接信息、映射文件的位置等配置信息。在啟動過程中,MyBatis會讀取并解析這個配置文件。
  2. 創建SqlSessionFactory對象:SqlSessionFactory是MyBatis的核心對象,用于創建SqlSession對象。在啟動過程中,MyBatis會根據配置文件中的信息,創建一個SqlSessionFactory對象。(工廠模式 ,建造者模式)
  3. 創建SqlSession對象:SqlSession是MyBatis的會話對象,用于執行數據庫操作。在啟動過程中,MyBatis會根據SqlSessionFactory對象,創建一個SqlSession對象。
  4. 加載映射文件:映射文件是MyBatis的另一個重要配置,用于定義SQL語句與Java方法之間的映射關系。在啟動過程中,MyBatis會根據配置文件中的信息,加載映射文件。(Mapper文件中的namespace+id)
  5. 初始化Mapper接口:Mapper接口是用于執行SQL語句的Java接口,在啟動過程中,MyBatis會根據映射文件中的信息,動態生成Mapper接口的實現類。
  6. 完成啟動:啟動過程完成后,就可以使用SqlSession對象執行數據庫操作了。

實現測試類,并測試

//1.讀取mybatis的核心配置文件(mybatis-config.xml)
//2.通過配置信息獲取一個SqlSessionFactory工廠對象
//3.通過工廠獲取一個SqlSession對象
//4.通過namespace+id找到要執行的sql語句并執行sql語句
//5.輸出結果
在這里插入圖片描述
image.png也就是 SqlSessionFactory對象的構建和 SqlSession對象創建的核心過程。已經具體的數據庫操作的請求是如何實現的。這塊也是面試官比較感興趣的內容。

  • SqlSessionFactory:全局配置文件的加載解析和映射文件的加載解析
  • SqlSession:相關的核心Executor和攔截器的實例化
  • Executor:處理具體的請求涉及到緩存處理。分頁擴展以及Sql解析和參數解析等

https://mybatis.net.cn/getting-started.html

SqlSessionFactory

  • SqlSessionFactory 一旦被創建就應該在應用的運行期間一直存在,沒有任何理由丟棄它或重新創建另一個實例。
  • 使用 SqlSessionFactory 的最佳實踐是在應用運行期間不要重復創建多次,多次重建 SqlSessionFactory
    被視為一種代碼“壞習慣”。因此 SqlSessionFactory 的最佳作用域是應用作用域。
    有很多方法可以做到,最簡單的就是使用單例模式或者靜態單例模式。

SqlSession

  • 每個線程都應該有它自己的 SqlSession 實例。SqlSession 的實例不是線程安全的,因此是不能被共享的,所以它的最佳的作用域是請求或方法作用域。
  • 絕對不能將 SqlSession 實例的引用放在一個類的靜態域,甚至一個類的實例變量也不行。 也絕不能將 SqlSession 實例的引用放在任何類型的托管作用域中,比如 Servlet 框架中的 HttpSession。
  • 如果你現在正在使用一種 Web 框架,考慮將 SqlSession 放在一個和 HTTP 請求相似的作用域中。 換句話說,每次收到HTTP 請求,就可以打開一個 SqlSession,返回一個響應后,就關閉它。這個關閉操作很重要,為了確保每次都能執行關閉操作,你應該把這個關閉操作放到 finally 塊中。

下面的示例就是一個確保 SqlSession 關閉的標準模式:

try (SqlSession session = sqlSessionFactory.openSession()) {// 你的應用邏輯代碼
}

在所有代碼中都遵循這種使用模式,可以保證所有數據庫資源都能被正確地關閉。

SqlSession有數據安全問題?

在MyBatis中,SqlSession是一個線程不安全的對象

主要原因如下:

  1. SqlSession的底層實現是基于JDBC的Connection對象,而Connection對象是非線程安全的,因此SqlSession也是非線程安全的。
  2. SqlSession中包含了數據庫連接和事務相關的操作,如果多個線程共享同一個SqlSession實例,可能會導致數據的 不一致性或者 事務的混亂
  3. SqlSession中的 緩存機制也是基于當前線程的,如果多個線程共享同一個SqlSession實例,可能會導致緩存的數據混亂或者不一致。

如何解決這個問題?

  • 為了保證數據的安全性和一致性,通常建議在每個線程中使用獨立的SqlSession實例,可以通過工廠模式創建新的SqlSession對象,或者使用MyBatis提供的線程安全的SqlSessionFactory實例來創建SqlSession。
  • 另外,可以使用ThreadLocal來保證每個線程中使用的SqlSession對象是唯一的

Spring整合MyBatis的解決方案

在Spring中,可以通過使用SqlSessionTemplate`來解決SqlSession數據不安全的問題

  • SqlSessionTemplate是MyBatis-Spring提供的一個實現了 SqlSession`接口的類,它會自動管理SqlSession的生命周期,并保證每個線程都有自己的SqlSession實例
  • 使用SqlSessionTemplate時,只需要將其配置為Spring的Bean,并注入到需要使用SqlSession的地方即可,Spring會自動為每個線程提供一個獨立的SqlSession實例。

image.png

攔截器

1 攔截器的定義

MyBatis 允許你在映射語句執行過程中的某一點進行攔截調用。默認情況下,MyBatis 允許使用插件來攔截的方法調用包括: https://mybatis.net.cn/configuration.html#plugins

在這里插入圖片描述
MyBatis 允許你在映射語句執行過程中的某一點進行攔截調用。默認情況下,MyBatis 允許使用插件來攔截的方法調用包括:

  • Executor(update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler(getParameterObject, setParameters)
  • ResultSetHandler(handleResultSets, handleOutputParameters)
  • StatementHandler(prepare, parameterize, batch, update, query)

這些類中方法的細節可以通過查看每個方法的簽名來發現,或者直接查看 MyBatis 發行包中的源代碼。 如果你想做的不僅僅是監控方法的調用,那么你最好相當了解要重寫的方法的行為。 因為在試圖修改或重寫已有方法的行為時,很可能會破壞 MyBatis 的核心模塊。 這些都是更底層的類和方法,所以使用插件的時候要特別當心。

2 攔截器的應用

MyBatis攔截器是MyBatis提供的一種插件機制,可以在SQL執行過程中攔截SQL語句并進行相關操作。

攔截器可以用于實現一些通用的功能,如日志記錄、權限校驗、性能監控等。它可以攔截SQL的執行、參數的設置、結果的處理等環節。

要實現一個攔截器,需要實現MyBatis提供的Interceptor接口,并重寫其中的方法。Interceptor接口中定義了3個方法:

  1. intercept:攔截方法,用于在SQL執行前后進行一些操作。在該方法中可以通過Invocation.proceed()方法調用下一個攔截器或執行目標方法。
  2. plugin:用于包裝目標對象,返回一個代理對象。可以通過該方法為目標對象生成一個代理對象,以便攔截對目標對象的方法調用。
  3. setProperties:用于設置攔截器的屬性。可以通過該方法獲取配置文件中的屬性,并進行相應的初始化操作。

??攔截器在MyBatis的配置文件中進行配置,可以通過標簽將攔截器添加到MyBatis的攔截鏈中。使用攔截器可以方便地擴展MyBatis的功能,實現一些通用的需求,并且可以靈活地控制攔截器的順序。

使用的步驟:

先定義

// ExamplePlugin.java
@Intercepts({@Signature(type= Executor.class,method = "update",args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {private Properties properties = new Properties();public Object intercept(Invocation invocation) throws Throwable {// implement pre processing if needObject returnObject = invocation.proceed();// implement post processing if needreturn returnObject;}public void setProperties(Properties properties) {this.properties = properties;}
}

再注冊

<!-- mybatis-config.xml -->
<plugins><plugin interceptor="org.mybatis.example.ExamplePlugin"><property name="someProperty" value="100"/></plugin>
</plugins>

上面的插件將會攔截在 Executor 實例中所有的 “update” 方法調用, 這里的 Executor 是負責執行底層映射語句的內部對象。

image.png

實際的應用:分頁,SQL檢查。黑白名單。分庫分表等

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/209699.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/209699.shtml
英文地址,請注明出處:http://en.pswp.cn/news/209699.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vuex如何存儲數據、獲取數據、以及數據的持久化

前提必須已經在vue中安裝了vuex插件不然無法使用&#xff0c;不知道怎么創建vue和安裝vuex的可以看這個視頻&#xff0c;node.js版本最好16以上不然可能會安裝失敗&#xff1a;30分鐘學會Vue之VueRouter&Vuex 趁著暑假掌握一門技能 大學生前端實習畢業設計必備技能_嗶哩嗶哩…

好代碼資源網整站打包代碼(包含了最新數據),集成了深度二開的ripro主題,非常適合做資源網站創業用

好代碼資源網是基于wordpress開發的一個資源分享類網站&#xff0c;在開發者圈子里還算小有名氣&#xff0c;這里分享嬰整站打包代碼&#xff08;包含了最新數據&#xff09;。網站本身集成了深度二開的ripro主題&#xff0c;非常適合做資源網站創業用。 資源下載類網站目前還…

Button背景顏色改不了,一直是默認的紫色

使用android.widget.Button <android.widget.Buttonandroid:layout_width"wrap_content"android:layout_height"wrap_content"android:onClick"doClick"android:text"這是一個按鈕"android:textColor"color/black"androi…

kubesphere安裝后啟用DevOps

官方文檔&#xff1a;KubeSphere DevOps 系統 1、集群管理---定制資源定義 進入目錄&#xff1a;集群管理---定制資源定義搜索&#xff1a;clusterconfiguration 點擊 ks-installer 右側的 &#xff0c;選擇編輯 YAML 在該 YAML 文件中&#xff0c;搜索 devops&#xff0c;…

力扣98. 驗證二叉搜索樹

深度優先遍歷 思路&#xff1a; 根據二叉搜索樹特性&#xff0c;通過中序遍歷得到有序序列&#xff0c;驗證序列是否有序來判斷&#xff1b;中序遍歷使用棧通過深度優先遍歷&#xff1b; /*** Definition for a binary tree node.* struct TreeNode {* int val;* Tre…

No CUDA GPUs are available

文章目錄 前言嘗試方法一、嘗試方法一二、嘗試方法二 總結 前言 之前用服務器跑的時候&#xff0c;發現是可以跑的。但當有其他人一同使用的時候&#xff0c;就會拋出&#xff1a;No CUDA GPUs are available&#xff0c;這個時候我嘗試了以下兩種方式解決&#xff0c;后面終于…

一到冬天,助聽器出現聲音小、無聲、時有時無……

冬天是一個寒冷干燥的季節&#xff0c;對于助聽器的使用者來說&#xff0c;也是一個需要特別注意保養的季節。助聽器是高精密的電子產品&#xff0c;如果不注意保養&#xff0c;可能會出現聲音小、無聲、時有時無等故障&#xff0c;影響聽力康復的效果。那么&#xff0c;冬天我…

C++中string類的使用

目錄 一.string類 1.1為什么學習string類&#xff1f; 1.2.標準庫中的string類 二.string對象的元素訪問 2.1.1使用operator[]與at實現訪問 2.1.2正向迭代器訪問 2.1.3反向迭代器訪問 2.1.4const正向迭代器&#xff08;不能修改&#xff09; 2.1.5const反向迭代器&#…

計算機網絡知識點合集【王道計算機考研】

學習的最大理由是想擺脫平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;遲一天就多一天平庸的困擾。各位小伙伴&#xff0c;如果您&#xff1a; 想系統/深入學習某技術知識點… 一個人摸索學習很難堅持&#xff0c;想組團高效學習… 想寫博客但無從下手&#xff0c;急需…

維護真實時間:應對系統時間篡改的技巧

引言 在App使用中&#xff0c;由于系統時間用戶可以隨意更改&#xff0c;在某些特殊情況下會導致獲取到的系統時間不正確問題。本篇代碼使用dart語言進行相關描述。 1.問題分析&#xff1a; 手機系統時間 ≠ 真實時間&#xff0c;當我們做一些需要對時間精度和準確性要求較高的…

SQL命令---修改數據庫的編碼

介紹 使用sql命令修改數據庫的編碼&#xff0c;修改為utf8mb4編碼。 命令 alter database 數據庫名稱 default character set utf8mb4;

垃圾收集算法和各種垃圾收集器的實現

深入理解Jvm虛擬機第三章 二、對象已死&#xff1f;3.2.1 引用計數算法3.2.2 可達性分析算法3.2.3 再談引用3.2.4 生存還是死亡3.2.5 回收方法區 三、垃圾收集算法3.3.1 分代收集理論3.3.2 標記-清除算法3.3.3 標記-復制算法3.3.4 標記-整理算法 四、HotSpot的算法細節實現3.4.…

單片機中的printf思考

問題: 1. printf自帶的庫編譯出來的大小比較大(flash吃緊) 2. printf是一個不定長參數, 意味著函數無法知道傳入的長度. 解決這個問題有2中方法:1.設置足夠大小的數組作為參數存儲; 2. 使用動態內存分配的方式來做(應該使用的是這個方式).(內存吃緊) 問題解釋: 1. 之前寫裸…

C# WPF上位機開發(串口界面設計)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】 如果只是把上位機看成是純軟件開發&#xff0c;本身不和硬件打交道的話&#xff0c;那么這就把上位機的操作范圍給限定死了。事實上&#xff0c;上…

多線程的使用

進程與線程 進程&#xff1a; 1、進程是指運行中的程序&#xff0c;比如我們使用QQ&#xff0c;就啟動了一個進程&#xff0c;操作系統就會為該進程分配內存空間。當我們使用微信&#xff0c;又啟動了一個進程,操作系統將為其分配新的內存空間。 2、進程是程序的一次執行過程…

數據庫系統概論期末經典大題講解(范式提升、求閉包、求主碼)

上一次我們介紹了數據庫中關系代數查詢&#xff0c;從選擇、投影到連接等操作符&#xff0c;探索了數據庫查詢 大家可以移步我的文章&#xff1a;數據庫系統概論期末經典大題講解&#xff08;用關系代數進行查詢&#xff09;-CSDN博客 今天&#xff0c;我們將繼續沿著數據庫系統…

《python每天一小段》--12 數據可視化《1》

歡迎閱讀《Python每天一小段》系列&#xff01;在本篇中&#xff0c;將使用Python Matplotlib實現數據可視化的簡單圖形。 一、概念 Matplotlib是一個流行的Python數據可視化庫&#xff0c;它提供了豐富的繪圖功能&#xff0c;可以創建各種類型的圖表&#xff0c;包括折線圖、…

Spring框架學習:Bean生命周期

目錄 SpringBean的生命周期 Bean實例屬性填充 三級緩存 常用的Aware接口 Spring IoC容器實例化Bean總結 SpringBean的生命周期 Spring Bean的生命周期是從 Bean 實例化之后&#xff0c;即通過反射創建出對象之后&#xff0c;到Bean成為一個完整對象&#xff0c;最終存儲到…

【MyBatis系列】MyBatis字符串問題

&#x1f49d;&#x1f49d;&#x1f49d;歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:kwan 的首頁,持續學…

SpringBoot + Spring Cloud Alibaba + Nacos實現服務管理

1、參考文檔 Spring Cloud Alibaba參考文檔 https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/zh-cn/index.html Spring Cloud Alibaba官方文檔 https://github.com/alibaba/spring-cloud-alibaba/wiki/ 2、引入 Alibaba 依賴 每個 SpringBoot 都有對應的…