深入掌握MyBatis:連接池、動態SQL、多表查詢與緩存

文章目錄

  • 一、MyBatis連接池
    • 1.1 連接池的作用
      • 1.2 MyBatis連接池分類
  • 二、動態SQL
    • 2.1 if標簽
    • 2.2 where標簽
    • 2.3 foreach標簽
    • 2.4 SQL片段復用
  • 三、多表查詢
      • 3.1 多對一查詢(一對一)
      • 3.2 一對多查詢
  • 四、延遲加載
      • 4.1 立即加載 vs 延遲加載
      • 4.2 配置延遲加載
  • 五、MyBatis緩存
    • 5.1 一級緩存
    • 5.2 二級緩存
    • 5.3 一級緩存 vs 二級緩存:核心差異
    • 5.4 緩存使用陷阱與最佳實踐**
  • 總結

一、MyBatis連接池

1.1 連接池的作用

  • 什么是連接池:存儲數據庫連接的容器,避免頻繁創建和銷毀連接。
  • 解決的問題:每次執行SQL都創建連接會浪費資源,連接池復用連接提升性能。

1.2 MyBatis連接池分類

類型描述
POOLED使用連接池(默認)
UNPOOLED不使用連接池(適合簡單場景)
JNDI通過JNDI獲取外部連接池

配置示例

<dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/test"/><property name="username" value="root"/>
</dataSource>

二、動態SQL

2.1 if標簽

動態拼接查詢條件,避免手動拼接SQL字符串。

<select id="findByWhere" resultType="User">SELECT * FROM user<where><if test="username != null">AND username LIKE #{username}</if><if test="sex != null">AND sex = #{sex}</if></where>
</select>

2.2 where標簽

自動處理WHERE后的AND/OR冗余,替代WHERE 1=1

<where><if test="username != null">username LIKE #{username}</if>
</where>

2.3 foreach標簽

遍歷集合生成條件,支持INOR拼接。

<!-- IN (1,2,3) -->
<foreach collection="ids" item="i" open="id IN (" separator="," close=")">#{i}
</foreach><!-- OR id=1 -->
<foreach collection="ids" item="i" open="id=" separator=" OR id=">#{i}
</foreach>

2.4 SQL片段復用

提取公共SQL片段,減少重復代碼。

<sql id="baseSelect">SELECT * FROM user</sql>
<select id="findAll"><include refid="baseSelect"/>
</select>

三、多表查詢

3.1 多對一查詢(一對一)

需求:查詢賬戶信息并關聯用戶信息。

JavaBean

public class Account {private Integer id;private Double money;private User user; // 關聯用戶
}

XML配置

<resultMap id="accountMap" type="Account"><id property="id" column="id"/><association property="user" javaType="User"><result property="username" column="username"/></association>
</resultMap><select id="findAll" resultMap="accountMap">SELECT a.*, u.username FROM account a JOIN user u ON a.uid = u.id
</select>

3.2 一對多查詢

需求:查詢用戶及其所有賬戶。

JavaBean

public class User {private List<Account> accounts; // 用戶擁有多個賬戶
}

XML配置

<resultMap id="userMap" type="User"><collection property="accounts" ofType="Account"><result property="money" column="money"/></collection>
</resultMap><select id="findOneToMany" resultMap="userMap">SELECT u.*, a.money FROM user u LEFT JOIN account a ON u.id = a.uid
</select>

四、延遲加載

延遲加載,也叫懶加載,簡單來說就是在真正需要數據的時候才去加載數據,而不是在一開始就把所有關聯數據都加載出來。這可以有效減少資源的浪費,尤其是在處理復雜對象關系時,避免一次性加載大量無用數據。

4.1 立即加載 vs 延遲加載

  • 立即加載:查詢主對象時,直接加載關聯對象(默認)。
  • 延遲加載:按需加載關聯對象,提升性能。

4.2 配置延遲加載

開啟全局延遲加載

<settings><setting name="lazyLoadingEnabled" value="true"/><setting name="aggressiveLazyLoading" value="false"/>
</settings>

一對一延遲加載示例
假設有 UserAddress 兩個實體,一個用戶對應一個地址。在傳統的查詢方式中,可能會一次性將用戶及其地址信息都查詢出來。但在延遲加載模式下,查詢用戶時并不會立即查詢地址信息。

然后在 User 的映射文件中配置:

<resultMap id="userMap" type="User"><id column="user_id" property="id"/><result column="username" property="username"/><association property="address" select="cn.tx.mapper.AddressMapper.findAddressByUserId" column="user_id" fetchType="lazy"/>
</resultMap>

這樣,當查詢用戶時,只有在訪問 user.getAddress() 時才會去查詢地址信息。

多對一延遲加載示例
比如多個訂單對應一個用戶,在查詢訂單時,用戶信息可以延遲加載。在 Order 的映射文件中配置:

<resultMap id="orderMap" type="Order"><id column="order_id" property="id"/><result column="order_no" property="orderNo"/><association property="user" select="cn.tx.mapper.UserMapper.findUserByOrderId" column="user_id" fetchType="lazy"/>
</resultMap>

當訪問 order.getUser() 時才會加載用戶信息。

一對多延遲加載示例
User 的映射文件中配置如下:

<resultMap id="userMap" type="User"><id column="user_id" property="id"/><result column="username" property="username"/><collection property="orders" select="cn.tx.mapper.OrderMapper.findOrdersByUserId" column="user_id" fetchType="lazy"/>
</resultMap>

只有在調用 user.getOrders() 時,才會執行查詢訂單的SQL語句。

多對多延遲加載示例
假設 UserRole 是多對多關系,需要通過中間表 user_role 來關聯。

首先在 User 的映射文件中配置:

<resultMap id="userMap" type="User"><id column="user_id" property="id"/><result column="username" property="username"/><collection property="roles" select="cn.tx.mapper.RoleMapper.findRolesByUserId" column="user_id" fetchType="lazy"/>
</resultMap>

Role 的映射文件中也做類似配置:

<resultMap id="roleMap" type="Role"><id column="role_id" property="id"/><result column="role_name" property="roleName"/><collection property="users" select="cn.tx.mapper.UserMapper.findUsersByRoleId" column="role_id" fetchType="lazy"/>
</resultMap>

這樣在查詢用戶或角色時,相關聯的多對多關系數據只有在實際訪問時才會加載。

五、MyBatis緩存

5.1 一級緩存

1. 定義與特性

  • 作用范圍SqlSession 級別,默認開啟。
  • 生命周期:與 SqlSession 綁定,Session 關閉或執行 commit()/rollback() 時清空。
  • 工作機制:同一個 Session 內多次執行 相同查詢,優先從緩存讀取。
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user1 = mapper.findById(1); // 第一次查詢,從數據庫獲取數據并放入一級緩存
User user2 = mapper.findById(1); // 第二次查詢,從一級緩存中獲取數據

2. 緩存命中與失效

  • 命中條件:相同的 SQL + 相同的參數 + 相同的環境。
  • 失效場景
    • 執行 INSERT/UPDATE/DELETE 操作。
    • 手動調用 sqlSession.clearCache()
    • SqlSession 的查詢不會共享緩存。

3. 實戰注意點

  • 坑點:跨方法調用時,若使用不同 SqlSession,一級緩存不共享。
  • 適用場景:短生命周期操作(如單次請求內的重復查詢)。

5.2 二級緩存

1. 定義與特性

  • 作用范圍Mapper 級別(跨 SqlSession),需手動開啟。
  • 生命周期:與應用進程綁定,重啟或調用 clear() 時清空。
  • 存儲結構:序列化后的數據(需實體類實現 Serializable)。

2. 緩存策略與配置

  • 開啟步驟
    <!-- MyBatis 全局配置 -->
    <settings><setting name="cacheEnabled" value="true"/>
    </settings><!-- Mapper XML 中聲明 -->
    <mapper namespace="..."><cache eviction="LRU" flushInterval="60000" size="512"/>
    </mapper>
    
  • 淘汰策略eviction):
    • LRU:最近最少使用(默認)。
    • FIFO:先進先出。
    • SOFT:軟引用,基于垃圾回收器狀態回收。

3. 工作流程

  1. 查詢順序:二級緩存 → 一級緩存 → 數據庫。
  2. 數據提交SqlSession 關閉時,一級緩存數據同步到二級緩存。

5.3 一級緩存 vs 二級緩存:核心差異

維度一級緩存二級緩存
作用范圍SqlSessionSqlSession(同一 Mapper)
默認狀態開啟需手動配置
存儲位置內存(JVM 堆)可配置為磁盤或第三方緩存(如 Redis)
數據共享不共享多個 Session 共享
生命周期隨 Session 銷毀長期存在,需主動管理

5.4 緩存使用陷阱與最佳實踐**

1. 常見問題

  • 臟讀風險:跨服務節點時,二級緩存可能導致數據不一致。
  • 序列化開銷:二級緩存序列化影響性能,需權衡緩存粒度。
  • 緩存穿透:頻繁查詢不存在的數據,需設置空值緩存。

2. 優化建議

  • 合理配置:根據數據更新頻率選擇緩存策略(如 flushInterval)。
  • 第三方緩存:集成 Redis 或 Ehcache 實現分布式緩存。
  • 注解控制:使用 @CacheNamespace@CacheNamespaceRef 精細化管理。

總結

掌握這些核心技能,可以高效利用MyBatis構建健壯的數據庫應用。實際開發中,需根據業務場景選擇合適策略,平衡性能與功能需求。

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

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

相關文章

TDesign AI Chat - Vue3.x 可用!騰訊出品的 AIGC 交互對話組件,免費開源、包含設計資源

各位前端開發者有遇到做 AI Chat 項目的聊天交互界面需求了嗎&#xff1f;TDesign 出品的這個組件很不錯&#xff0c;推薦給大家。 TDesign AI Chat 是 TDesign 為 AIGC 場景開發的 UI 系列組件中的一部分&#xff0c;主要用于開發目前非常流行的 ChatBot 對話交互場景。最近 …

spring -MVC-02

SpringMVC-11 - 響應 在 SpringMVC 中&#xff0c;響應是服務器對客戶端請求的反饋&#xff0c;它可以以多種形式呈現&#xff0c;包括視圖名稱、ModelAndView 對象、JSON 數據以及重定向等。以下是對 SpringMVC 中不同響應類型的詳細介紹&#xff1a; 1. 視圖名稱 通過返回…

老舊設備升級利器:Modbus TCP轉 Profinet讓能效監控更智能

在工業自動化領域&#xff0c;ModbusTCP和Profinet是兩種常見的通訊協議。Profinet是西門子公司推出的基于以太網的實時工業以太網標準&#xff0c;而Modbus則是由施耐德電氣提出的全球首個真正開放的、應用于電子控制器上的現場總線協議。這兩種協議各有各的優點&#xff0c;但…

ubuntu下docker安裝mongodb-支持單副本集

1.mogodb支持事務的前提 1) MongoDB 版本&#xff1a;確保 MongoDB 版本大于或等于 4.0&#xff0c;因為事務支持是在 4.0 版本中引入的。 2) 副本集配置&#xff1a;MongoDB 必須以副本集&#xff08;Replica Set&#xff09;模式運行&#xff0c;即使是單節點副本集&#x…

【前端開發】Uniapp日期時間選擇器:實現分鐘動態步長設置

技術棧 Uniapp + Vue3 + uView年份顯示前后一年,分鐘動態設置間隔效果圖 主體顯示<view class="uni-row-between selector"><view class="uni-flex-1 left" @click="!props.disabled && openPicker()"><uni-iconscolor=…

iOS 藍牙開發中的 BT 與 BLE

在 iOS 開發者的語境里&#xff0c;大家把 BT 和 BLE 當成兩種不同的藍牙技術在談——它們來自同一個 Bluetooth 規范&#xff0c;但面向的場景、協議棧乃至 Apple 提供的 API 都截然不同。 縮寫全稱 / 技術名稱規范層叫法iOS 支持現狀典型用途BTBluetooth Classic&#xff08…

Flink CEP是什么?

Apache Flink 的 CEP&#xff08;Complex Event Processing&#xff0c;復雜事件處理&#xff09; 是 Flink 提供的一個庫&#xff0c;用于在無界數據流中檢測符合特定模式的事件組合。 &#x1f3af; 一、什么是 CEP&#xff1f; ? 定義&#xff1a; CEP 是一種從連續的數據…

ARM (Attention Refinement Module)

ARM模塊【來源于BiSeNet】&#xff1a;細化特征圖的注意力&#xff0c;增強重要特征并抑制不重要的特征。 Attention Refinement Module (ARM) 詳解 ARM (Attention Refinement Module) 是 BiSeNet 中用于增強特征表示的關鍵模塊&#xff0c;它通過注意力機制來細化特征圖&…

AR0144CSSC20SUKA0-CRBR——1/4英寸 1.0 MP 高性能CMOS圖像傳感器解析

產品概述&#xff1a; AR0144CSSC20SUKA0-CRBR 是一款1/4 英寸&#xff0c;1.0 Mp CMOS 數字圖像傳感器&#xff0c;帶有 1280H x 800V 有效像素陣列 全局快門CMOS數字圖像傳感器&#xff0c;它結合了新型的創新全局快門像素設計&#xff0c;適用于準確快速的移動場景捕捉。該…

深入理解遞歸算法:Go語言實現指南

深入理解遞歸算法&#xff1a;Go語言實現指南 引言 遞歸是編程中一種優雅而強大的算法思想&#xff0c;通過函數自我調用的方式解決復雜問題。本文將使用Go語言演示遞歸的核心原理&#xff0c;并通過典型示例幫助開發者掌握這一重要技術。 一、遞歸基礎概念 1.1 遞歸定義 遞歸…

vue2實現【瀑布流布局】

瀑布流 1. 解釋2. 形成結構和樣式3. 自定義指令 1. 解釋 瀑布流特征&#xff1a; 等寬不等高&#xff1a;元素寬度固定&#xff0c;高度根據內容自適應。錯落排列&#xff1a;元素像瀑布一樣從上到下依次填充&#xff0c;自動尋找最短列插入 體現&#xff1a;圖中第一排1&…

CSS display有幾種屬性值

在 CSS 中&#xff0c;display 屬性是控制元素布局和渲染方式的核心屬性之一。它有多種屬性值&#xff0c;每個值都決定了元素在文檔流中的表現形式。以下是 display 的主要屬性值分類及說明&#xff1a; 1. 塊級和行內布局 塊級元素 (block) 特性&#xff1a;獨占一行&…

基于Java實現可靠傳輸

實現可靠傳輸 1. 結合代碼和 LOG 文件分析針對每個項目舉例說明解決效果。 RDT1.0 對應 Log 日志&#xff1a;Log 1.0.txt&#xff0c;接收文件 recvData 1.0.txt RDT1.0 版本是在可靠信道上進行可靠的數據傳輸&#xff0c;因此沒有過多的內容需要說明&#xff0c;發送方 L…

機器學習10-隨機森林

隨機森林學習筆記 一、隨機森林簡介 隨機森林&#xff08;Random Forest&#xff09;是一種集成學習算法&#xff0c;基于決策樹構建模型。它通過組合多個決策樹的結果來提高模型的準確性和穩定性。隨機森林的核心思想是利用“集成”的方式&#xff0c;將多個弱學習器組合成一…

LeetCode 438. 找到字符串中所有字母異位詞 | 滑動窗口與字符計數數組解法

文章目錄 問題描述核心思路&#xff1a;滑動窗口 字符計數數組1. 字符計數數組2. 滑動窗口 算法步驟完整代碼實現復雜度分析關鍵點總結類似問題 問題描述 給定兩個字符串 s 和 p&#xff0c;要求找到 s 中所有是 p 的**字母異位詞&#xff08;Anagram&#xff09;**的子串的起…

idea中,git的cherry-pick怎么用

背景: A同學在A分支進行開發, B同學在B分支進行開發,B同學開發過程中發現,A同學在A分支上面的某次提交,例如某次提交了一個工具類,B同學也用的到這個工具類,但是B又不想mergeA分支的代碼,此時就可以用到git的chery pick能力.

深入解析:如何基于開源OpENer開發EtherNet/IP從站服務

一、EtherNet/IP協議概述 EtherNet/IP(Industrial Protocol)是一種基于以太網的工業自動化通信協議,它將CIP(Common Industrial Protocol)封裝在標準以太網幀中,通過TCP/IP和UDP/IP實現工業設備間的通信。作為ODVA(Open DeviceNet Vendors Association)組織的核心協議…

當 PyIceberg 和 DuckDB 遇見 AWS S3 Tables:打造 Serverless 數據湖“開源夢幻組合”

引言 在一些大數據分析場景比如電商大數據營銷中&#xff0c;我們需要快速分析存儲海量用戶行為數據&#xff08;如瀏覽、加購、下單&#xff09;&#xff0c;以進行用戶行為分析&#xff0c;優化營銷策略。傳統方法依賴 Spark/Presto 集群或 Redshift 查詢 S3 上的 Parquet/O…

流復備機斷檔處理

文章目錄 環境癥狀問題原因解決方案 環境 系統平臺&#xff1a;UOS&#xff08;海光&#xff09;,UOS &#xff08;飛騰&#xff09;,UOS&#xff08;鯤鵬&#xff09;,UOS&#xff08;龍芯&#xff09;,UOS &#xff08;申威&#xff09;,銀河麒麟svs&#xff08;X86_64&…

【藍橋杯真題精講】第 16 屆 Python A 組(省賽)

文章目錄 T1 偏藍 (5/5)T2 IPv6 (0/5)T3 2025 圖形 (10/10)T4 最大數字 (10/10)T5 倒水 (15/15)T6 拼好數 (0/15)T7 登山 (20/20)T8 原料采購 (20/20) 更好的閱讀體驗 高速訪問&#xff1a;https://wiki.dwj601.cn/ds-and-algo/lan-qiao-cup/16th-python-a/永久鏈接&#xff1…