SpringBoot分布式項目中MyBatis實戰技巧:從配置到性能優化

引言

在分布式系統架構中,SpringBoot與MyBatis的組合已成為企業級開發的黃金搭檔。但在實際項目中,開發者常面臨多數據源管理、SQL性能優化、分布式事務等挑戰。本文將從實戰角度出發,分享7個關鍵技巧和避坑指南。


一、多數據源動態切換實戰

1.1 多數據源配置

@Configuration
public class DataSourceConfig {@Bean(name = "masterDataSource")@ConfigurationProperties(prefix = "spring.datasource.master")public DataSource masterDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "slaveDataSource")@ConfigurationProperties(prefix = "spring.datasource.slave")public DataSource slaveDataSource() {return DataSourceBuilder.create().build();}
}

1.2 動態數據源路由

public class DynamicDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.getDataSourceType();}
}// 使用AOP實現自動切換
@Around("execution(* com.example.service..*.*(..))")
public Object around(ProceedingJoinPoint point) {MethodSignature signature = (MethodSignature) point.getSignature();DataSourceSwitch dataSource = signature.getMethod().getAnnotation(DataSourceSwitch.class);if(dataSource != null){DataSourceContextHolder.setDataSourceType(dataSource.value());}// 執行方法...
}

注意點

  • 事務管理需使用@Transactional(transactionManager = "txManager")
  • 連接池推薦使用HikariCP
  • 讀寫分離場景建議結合AbstractRoutingDataSource+注解方式

二、MyBatis進階使用技巧

2.1 動態SQL最佳實踐

<select id="searchUsers" resultType="User">SELECT * FROM users<where><if test="name != null">AND name LIKE CONCAT('%',#{name},'%')</if><if test="status != null">AND status = #{status}</if><choose><when test="orderBy == 'name'">ORDER BY name</when><otherwise>ORDER BY create_time DESC</otherwise></choose></where>
</select>

2.2 自定義TypeHandler

處理枚舉類型和加密字段:

public class EncryptTypeHandler extends BaseTypeHandler<String> {private final Encryptor encryptor = new AESEncryptor();@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) {ps.setString(i, encryptor.encrypt(parameter));}// 其他方法實現解密...
}// 實體類使用
public class User {@TableField(typeHandler = EncryptTypeHandler.class)private String mobile;
}

三、性能優化三板斧

3.1 批量插入優化

public void batchInsert(List<User> users) {SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH);try {UserMapper mapper = sqlSession.getMapper(UserMapper.class);for (User user : users) {mapper.insert(user);}sqlSession.commit();} finally {sqlSession.close();}
}

3.2 二級緩存配置

<settings><setting name="cacheEnabled" value="true"/>
</settings><!-- Mapper級別開啟 -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

緩存策略建議

  • 讀多寫少的數據適合開啟緩存
  • 分布式環境建議集成Redis
  • 及時清理關聯表的緩存數據

四、分布式項目中的特殊處理

4.1 分頁查詢優化

// 使用PageHelper實現物理分頁
PageHelper.startPage(1, 10, "id DESC");
List<User> users = userMapper.selectByCondition(condition);
PageInfo<User> pageInfo = new PageInfo<>(users);// 深度分頁優化(基于游標)
@Select("SELECT * FROM users WHERE id > #{lastId} ORDER BY id LIMIT #{size}")
List<User> selectByScroll(@Param("lastId") Long lastId, @Param("size") int size);

4.2 SQL攔截器開發

公共字段自動填充插件示例:

@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
public class AutoFillInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {Object parameter = invocation.getArgs()[1];if(parameter instanceof BaseEntity){BaseEntity entity = (BaseEntity) parameter;entity.setUpdateTime(new Date());entity.setUpdater(getCurrentUser());}return invocation.proceed();}
}

五、避坑指南

5.1 警惕N+1查詢問題

<!-- 錯誤示范 -->
<resultMap id="userMap" type="User"><collection property="orders" select="selectOrdersByUserId" column="id"/>
</resultMap><!-- 正確方案:使用JOIN查詢 -->
<select id="selectUserWithOrders" resultMap="userOrderMap">SELECT u.*, o.* FROM users uLEFT JOIN orders o ON u.id = o.user_id
</select>

5.2 事務使用原則

  • 方法間調用避免this調用導致AOP失效
  • 只讀事務添加@Transactional(readOnly = true)
  • 分布式事務建議使用Seata方案

結語

在SpringBoot分布式架構中,合理運用MyBatis的特性可以顯著提升開發效率和系統性能。但切記:

  1. 多數據源配置要處理好事務邊界
  2. 動態SQL保持簡潔可維護
  3. 緩存策略需結合業務特點
  4. 監控慢SQL(推薦使用p6spy)

下一期預告:《SpringBoot+MyBatis整合Redis二級緩存實戰》——我們將深入探討如何構建高性能分布式緩存方案。

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

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

相關文章

【大模型基礎_毛玉仁】4.1 參數高效微調簡介

目錄 4 參數高效微調4.1 參數高效微調簡介4.1.1 下游任務適配1&#xff09;上下文學習&#xff08;In-context learning&#xff09;2&#xff09;指令微調&#xff08;Instruction Tuning&#xff09; 4.1.2 參數高效微調4.1.3 參數高效微調的優勢 4 參數高效微調 大語言模型…

Postman使用02、斷點、fiddler弱網測試

腳本操作 一、腳本導出 1.導出json腳本 2.打包json文件 3.下載的文件 二 .導入腳本 1.選擇文件 2.點擊導入 3.導入的接口 三.多接口運行 1.集合右鍵&#xff0c;點擊run &#xff0c;運行多個接口 2.編輯環境&#xff0c;集合&#xff0c;執行次數等 3.運行多個接口 四.運行…

深挖增長內核:好產品驅動增長的全方位解析

年前在老板的帶領下深入學習了《增長黑客》&#xff0c;并思考了在CPS站外引流的落地方案&#xff0c;最近剛好在做京東聯盟的京粉推客增長體系建設&#xff0c;再次回顧一下增長黑客方法以及記錄一下思考。 好產品才是增長的根本。增長黑客理念風靡&#xff0c;“啊哈時刻” 概…

新手小白 react-useEffect 使用場景

useEffect 是 React 中的一個非常重要的 Hook&#xff0c;用于處理組件的副作用&#xff08;side effects&#xff09;。它通常在以下幾種場景中使用&#xff1a; 1. 數據獲取 當組件加載時&#xff0c;需要從外部 API 獲取數據&#xff0c;或者從本地存儲中讀取數據。示例&a…

MySQL 調優:查詢慢除了索引還能因為什么?

文章目錄 情況一&#xff1a;連接數過小情況二&#xff1a;Buffer Pool 太小 MySQL 查詢慢除了索引還能因為什么&#xff1f;MySQL 查詢慢&#xff0c;我們一般也會想到是因為索引&#xff0c;但除了索引還有哪些原因會導致數據庫查詢變慢呢&#xff1f; 以下以 MySQL 中一條 S…

【操作系統】進程三種狀態?進程間狀態的切換?掛起態?

進程狀態 進程的五種&#xff08;三種&#xff09;狀態&#xff1a; 新建&#xff08;New&#xff09;&#xff1a;進程剛被創建&#xff0c;尚未加入到就緒隊列&#xff1b;就緒&#xff08;Ready&#xff09;&#xff1a;進程已獲得除CPU外的所有資源&#xff0c;等待被調度執…

計算機控制系統的最小拍控制器設計及仿真分析

1題目 開環傳遞函數 G(s) 2/(s(0.5s1)) &#xff0c;采樣周期 T0.5 秒&#xff0c;設計單位速度輸入下的最小拍控制器 1.1 方法1 根據課本中的步驟&#xff0c;最小拍控制器的設計步驟如下&#xff1a; 1. 確定對象的離散傳遞函數G(z)&#xff0c;并確定其零極點。 2. 確定…

哈希--哈希桶

哈希桶是哈希表&#xff08;散列表&#xff09;中的一個概念&#xff0c;是哈希表數組中的每個元素 &#xff0c;用于存儲鍵值對數據。它有以下特點和相關要點&#xff1a; 結構與原理&#xff1a;哈希表底層常由數組構成&#xff0c;數組的每個元素即哈希桶。通過哈希函數計算…

Linux多線程詳解

Linux多線程詳解 一、Linux多線程概念1.1 什么是線程1.2 進程和線程1.3 進程的多個線程共享1.4 進程和線程的關系 二、Linux線程控制2.1 POSIX線程庫2.2 線程創建2.3 獲取線程ID pthread_self2.4 線程等待pthread_join2.5 線程終止2.6 線程棧 && pthread_t2.7 線程的局…

Midscene.js自然語言驅動的網頁自動化全指南

一、概述 網頁自動化在數據抓取、UI 測試和業務流程優化中發揮著重要作用。然而&#xff0c;傳統工具如 Selenium 和 Puppeteer 要求用戶具備編程技能&#xff0c;編寫復雜的選擇器和腳本維護成本高昂。Midscene.js 通過自然語言接口革新了這一領域&#xff0c;用戶只需描述任…

winstart.wsf 病毒清理大作戰

0x00 背景 發現感染了winstart.wsf 病毒如何清理。 0x01 現象 遍歷Users下每個目錄以及C:\和C:\Windows\Temp 2個目錄寫入病毒文件。 C:\Users\Administrator\AppData\Local\Temp\winstart.wsf C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Program…

多路轉接Poll

在之前我們講過select是最古老的多路轉接方案&#xff0c;古老就意味著他不是很方便使用&#xff0c;他需要用戶手動保存fd_set這個位圖結構&#xff0c;來表示讀寫事件的關注與否或者就緒性。 而且由于fd_set的大小是固定的&#xff0c;這就意味著他能管理的套接字文件描述符是…

多層感知機的簡潔實現

《動手學深度學習》-4.3-筆記 import torch from torch import nn from d2l import torch as d2l 導入必要的庫和模塊 net nn.Sequential(nn.Flatten(),nn.Linear(784, 256),nn.ReLU(),nn.Linear(256, 10))def init_weights(m):if type(m) nn.Linear:nn.init.normal_(m.we…

【GoLang】調用llm時提示詞prompt的介紹以及使用方式

介紹 提示詞是一種與大模型交互的對話格式&#xff0c;它以 JSON 格式定義了一個消息列表&#xff08;messages&#xff09;&#xff0c;包含了系統消息和用戶消息。 我們向AI提問時&#xff0c;其實發給AI的都是提示詞&#xff0c;別看我們只是簡單輸入了一句話&#xff0c;…

內核編程十二:打印task_struct中的數據

在Linux內核中&#xff0c;current 是一個宏&#xff0c;用于獲取當前正在執行的進程的 task_struct 結構體指針。current 宏返回一個指向當前正在運行的進程的 task_struct 結構體的指針。通過這個指針&#xff0c;內核代碼可以訪問和修改當前進程的各種屬性和狀態。 打印單個…

區間端點(java)(貪心問題————區間問題)

deepseek給了一種超級簡單的做法 我是真的想不到 貪心的思路是 局部最優——>全局最優 這種我是真的沒有想到&#xff0c;這樣的好處就是后面便利的時候可以通過foreach循環直接便利qu的子元素也就是對應的某一個區間, 將一個二維數組變成一維數組&#xff0c;每一個一維…

Qt事件處理(處理鼠標事件、鍵盤事件、定時器事件、窗口移動和大小變化事件)

事件處理 事件是應用程序內部或者外部產生的事情或者動作的統稱。 在 Qt 中&#xff0c;事件是用一個對象來管理一個事件的。所有的事件對象都繼承自抽象類 QEvent 。事件包括鼠標事件、鍵盤事件等&#xff0c;發出自 Qt 或操作系統本身。 處理事件一般通過重寫相關的 Event 函…

Apache Hive:基于Hadoop的分布式數據倉庫

Apache Hive 是一個基于 Apache Hadoop 構建的開源分布式數據倉庫系統&#xff0c;支持使用 SQL 執行 PB 級大規模數據分析與查詢。 主要功能 Apache Hive 提供的主要功能如下。 HiveServer2 HiveServer2 服務用于支持接收客戶端連接和查詢請求。 HiveServer2 支持多客戶端…

利用 @eslint/eslintrc 實現 ESLint9的適配

深度解析&#xff1a;利用 eslint/eslintrc 實現 ESLint 的高效配置管理 在前端開發領域&#xff0c;代碼質量和一致性是至關重要的。ESLint 作為一款流行的代碼檢查工具&#xff0c;幫助開發者發現代碼中的潛在問題并保持代碼風格的一致性。而隨著項目的復雜度增加和團隊規模…

cfca 申請國密證書流程

之前給某銀行開發項目&#xff0c;需要用到cfca國密雙證證書&#xff0c;證書類型為企業雙證的作為接口加密的密鑰。 因為是第一次對接&#xff0c;其中走了不少的彎路&#xff0c;現將申請的流程發布出來做下記錄 1、需要找到cfca的相關人員進行測試證書的申請 2、大概1天的…