Spring Boot項目中結(jié)合MyBatis實現(xiàn)MySQL的自動主從切換功能
原理解析
1. MySQL主從復(fù)制(Master-Slave Replication)
- 工作原理:MySQL主從復(fù)制通過二進制日志(binary log)來同步數(shù)據(jù)。主服務(wù)器記錄所有更改操作到二進制日志中,從服務(wù)器讀取這些日志并執(zhí)行相應(yīng)的SQL語句來保持與主服務(wù)器的數(shù)據(jù)一致。
- 延遲問題:由于網(wǎng)絡(luò)傳輸和處理時間,從庫可能會有短暫的數(shù)據(jù)滯后,這對于需要實時一致性的場景是一個挑戰(zhàn)。
2. 讀寫分離
- 目的:提高系統(tǒng)性能和可用性。通過將讀請求分配給從庫,寫請求發(fā)送給主庫,可以減少主庫的壓力,提升系統(tǒng)的整體性能。
- 實現(xiàn)方式:可以通過數(shù)據(jù)庫中間件或框架層面的配置來實現(xiàn)。在這個例子中,我們使用Apache ShardingSphere來實現(xiàn)讀寫分離。
3. 自動故障轉(zhuǎn)移
- 原理:當檢測到主庫不可用時,系統(tǒng)會自動選擇一個從庫作為新的主庫,并重新調(diào)整讀寫分配。這通常涉及到心跳檢測、狀態(tài)監(jiān)控等機制。
- 工具支持:除了ShardingSphere外,還可以使用MHA(MySQL Master High Availability)或其他高可用解決方案。
實現(xiàn)步驟詳解
1. 引入依賴
在pom.xml中添加必要的依賴,包括Spring Boot Starter、MyBatis Starter以及ShardingSphere:
深色版本
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- MyBatis Starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!-- ShardingSphere for read-write splitting -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.1.1</version>
</dependency>
</dependencies>2. 配置數(shù)據(jù)源
編輯application.yml文件以配置多個數(shù)據(jù)源,并設(shè)置ShardingSphere規(guī)則以實現(xiàn)讀寫分離:
深色版本
spring:
shardingsphere:
datasource:
names: master,slave0,slave1
master:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://master_host:3306/your_db?useSSL=false&serverTimezone=UTC
username: your_username
password: your_password
slave0:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://slave0_host:3306/your_db?useSSL=false&serverTimezone=UTC
username: your_username
password: your_password
slave1:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://slave1_host:3306/your_db?useSSL=false&serverTimezone=UTC
username: your_username
password: your_password
masterslave:
load-balance-algorithm-type: round_robin # 負載均衡策略
name: ms_ds # 數(shù)據(jù)源名稱
master-data-source-name: master # 主庫數(shù)據(jù)源名稱
slave-data-source-names: slave0,slave1 # 從庫數(shù)據(jù)源名稱列表
props:
sql:
show: true # 是否顯示SQL語句3. 配置MyBatis
創(chuàng)建MyBatis Mapper接口,并使用注解或XML配置SQL語句。這里以注解方式為例:
深色版本
package com.example.demo.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
@Mapper
public interface UserMapper {
/**
* 查詢所有用戶信息.
* 注意:對于查詢操作,ShardingSphere會選擇其中一個從庫來執(zhí)行查詢。
*
* @return 用戶信息列表
*/
@Select("SELECT * FROM users")
List<Map<String, Object>> findAllUsers();
/**
* 更新用戶信息.
* 注意:寫操作只會針對主庫執(zhí)行。
*
* @param id 用戶ID
* @param newName 新用戶名
*/
void updateUserById(@Param("id") Long id, @Param("newName") String newName);
}確保你的Spring Boot應(yīng)用掃描到Mapper接口??梢栽谥黝惿咸砑?code>@MapperScan注解:
深色版本
package com.example.demo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}4. 使用Mapper進行數(shù)據(jù)庫操作
現(xiàn)在你可以在Service層中注入并使用Mapper接口來進行數(shù)據(jù)庫操作:
深色版本
package com.example.demo.service;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
/**
* 獲取所有用戶信息.
*
* @return 用戶信息列表
*/
public List<Map<String, Object>> getAllUsers() {
return userMapper.findAllUsers();
}
/**
* 更新用戶名稱.
*
* @param id 用戶ID
* @param newName 新用戶名
*/
public void updateUserName(Long id, String newName) {
userMapper.updateUserById(id, newName);
}
}注意事項及最佳實踐
- 事務(wù)管理:確保所有寫操作都在同一個事務(wù)中執(zhí)行,并且只對主庫進行寫操作??梢允褂?code>@Transactional注解來管理事務(wù)。
- 數(shù)據(jù)一致性:考慮到主從復(fù)制延遲的問題,在某些場景下(如剛完成寫操作后立即讀?。?,可能需要直接查詢主庫以保證數(shù)據(jù)一致性。
- 健康檢查:建議定期監(jiān)控主從狀態(tài),確保從庫同步正常以及主庫可訪問??梢酝ㄟ^定時任務(wù)或者外部工具來實現(xiàn)。
- 性能優(yōu)化:根據(jù)實際業(yè)務(wù)需求調(diào)整負載均衡策略,例如采用權(quán)重輪詢或其他高級算法來優(yōu)化查詢效率。
到此這篇關(guān)于Spring Boot項目中結(jié)合MyBatis實現(xiàn)MySQL的自動主從切換的文章就介紹到這了,更多相關(guān)Spring Boot MyBatis自動主從切換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java Spring Cloud Bus 實現(xiàn)配置實時更新詳解
這篇文章主要介紹了SpringCloud Bus如何實現(xiàn)配置刷新,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2021-09-09
Java根據(jù)實體生成SQL數(shù)據(jù)庫表的示例代碼
這篇文章主要來和大家分享一個Java實現(xiàn)根據(jù)實體生成SQL數(shù)據(jù)庫表的代碼,文中的實現(xiàn)代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2023-07-07
一文帶你完全掌握SpringBoot中配置的優(yōu)先級
在現(xiàn)代Spring Boot應(yīng)用開發(fā)中,理解配置文件的加載順序和優(yōu)先級至關(guān)重要,本文將深入剖析包括Nacos遠程配置、本地properties和yml文件在內(nèi)的各種配置源的優(yōu)先級關(guān)系,希望可以幫助開發(fā)者掌握配置管理的最佳實踐2026-03-03
Java枚舉類的規(guī)范設(shè)計與常見錯誤規(guī)避指南
在Java開發(fā)中,枚舉(enum)是一種強大的工具,用于定義一組固定常量集合,然而,許多開發(fā)者在使用枚舉時容易陷入設(shè)計誤區(qū),導(dǎo)致代碼可維護性差、運行時錯誤頻發(fā),甚至引發(fā)生產(chǎn)事故,所以本文給大家介紹了Java枚舉類的規(guī)范設(shè)計與常見錯誤規(guī)避,需要的朋友可以參考下2025-06-06
關(guān)于Spring Boot動態(tài)權(quán)限變更問題的實現(xiàn)方案
這篇文章主要介紹了Spring Boot動態(tài)權(quán)限變更實現(xiàn)的整體方案使用session作為緩存,結(jié)合AOP技術(shù)進行token認證和權(quán)限控制,本文給大家介紹的非常詳細,需要的朋友參考下吧2021-06-06
SpringBoot HTTP服務(wù)開發(fā)從入門到部署完整流程
本文將基于SpringBoot+Gradle技術(shù)棧,從零開始構(gòu)建一個簡單的HTTP服務(wù),逐步實現(xiàn)從項目初始化、API開發(fā)、業(yè)務(wù)邏輯構(gòu)建到最終部署上線的全流程,感興趣的朋友跟隨小編一起看看吧2026-02-02

