springboot~sharding-jdbc實現分庫分表

来源:https://www.cnblogs.com/lori/archive/2023/05/24/17427456.html
-Advertisement-
Play Games

# 原因 當mysql資料庫單表大於1千萬以後,查詢的性能就不能保證了,我們必須考慮分庫,分表的方案了,還好,sharding-jdbc可以很優雅的與springboot對接,完成對mysql的分庫和分表。 # 依賴整理 > 為了不影響其它小容量的表,所有添加了動態數據源,只對需要分庫分表的進行配置 ...


原因

當mysql資料庫單表大於1千萬以後,查詢的性能就不能保證了,我們必須考慮分庫,分表的方案了,還好,sharding-jdbc可以很優雅的與springboot對接,完成對mysql的分庫和分表。

依賴整理

為了不影響其它小容量的表,所有添加了動態數據源,只對需要分庫分表的進行配置即可

  • com.baomidou:dynamic-datasource-spring-boot-starter:3.3.1
  • org.apache.shardingsphere:sharding-jdbc-spring-boot-starter:4.1.1
  • com.baomidou:dynamic-datasource-spring-boot-starter:3.3.1
  • com.baomidou:mybatis-plus-boot-starter:3.4.1
    <dependency>
        <groupId>org.apache.shardingsphere</groupId>
        <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

配置整理

spring:
  application.name: sharding-jdbc
  datasource:
    dynamic:
      primary: master0
      datasource:
        master0:
          url: jdbc:mysql://192.168.4.xx:3306/sharding0?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
          username: root
          password: xxx
          driver-class-name: com.mysql.jdbc.Driver
        master1:
          url: jdbc:mysql://192.168.4.xx:3306/sharding1?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
          username: root
          password: xxx
          driver-class-name: com.mysql.jdbc.Driver

  shardingsphere:
    datasource:
      names: ds0,ds1
      ds0:
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://192.168.4.xx:3306/sharding0?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
        username: root
        password: xxx
        type: com.zaxxer.hikari.HikariDataSource
      ds1:
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://192.168.4.xx:3306/sharding1?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
        username: root
        password: xxx
        type: com.zaxxer.hikari.HikariDataSource #必須個type,否則報錯
    sharding:
      tables:
        t_order:
          #key-generator:
          #  column: id
          #  type: SNOWFLAKE
          actual-data-nodes: ds$->{0..1}.t_order_$->{0..1} #需要開發人員手動按規則建立數據表
          database-strategy:
            inline:
              sharding-column: id
              algorithm‐expression: ds$->{id % 2}
          table-strategy:
            inline:
              sharding-column: id
              algorithm‐expression: t_order_$->{id % 2}
    props:
      sql:
        show: true   # 日誌顯示SQL

mybatis:
  mapperLocations: classpath:mapper/*.xml
  typeAliasesPackage: com.lind.shardingjdbc.entity
  configuration:
    mapUnderscoreToCamelCase: true

提前建立表分庫和分表

測試代碼整理

  • 配置類
@Configuration
@AutoConfigureBefore({ DynamicDataSourceAutoConfiguration.class, SpringBootConfiguration.class })
public class DataSourceConfiguration {

	// 分表數據源名稱
	private static final String SHARDING_DATA_SOURCE_NAME = "sharding";
	/**
	 * shardingjdbc有四種數據源,需要根據業務註入不同的數據源
	 *
	 * <p>
	 * 1. 未使用分片, 脫敏的名稱(預設): shardingDataSource;
	 * <p>
	 * 2. 主從數據源: masterSlaveDataSource;
	 * <p>
	 * 3. 脫敏數據源:encryptDataSource;
	 * <p>
	 * 4. 影子數據源:shadowDataSource
	 */
	@Lazy
	@Resource(name = "shardingDataSource")
	AbstractDataSourceAdapter shardingDataSource;
	// 動態數據源配置項
	@Autowired
	private DynamicDataSourceProperties properties;

	@Bean
	public DynamicDataSourceProvider dynamicDataSourceProvider() {
		Map<String, DataSourceProperty> datasourceMap = properties.getDatasource();
		return new AbstractDataSourceProvider() {
			@Override
			public Map<String, DataSource> loadDataSources() {
				Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap);
				// 將 shardingjdbc 管理的數據源也交給動態數據源管理
				dataSourceMap.put(SHARDING_DATA_SOURCE_NAME, shardingDataSource);
				return dataSourceMap;
			}
		};
	}

	/**
	 * 將動態數據源設置為首選的 當spring存在多個數據源時, 自動註入的是首選的對象 設置為主要的數據源之後,就可以支持shardingjdbc原生的配置方式了
	 */
	@Primary
	@Bean
	public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
		DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
		dataSource.setPrimary(properties.getPrimary());
		dataSource.setStrict(properties.getStrict());
		dataSource.setStrategy(properties.getStrategy());
		dataSource.setProvider(dynamicDataSourceProvider);
		dataSource.setP6spy(properties.getP6spy());
		dataSource.setSeata(properties.getSeata());
		return dataSource;
	}

}
  • 實體類和mapper類
@Data
@TableName("t_order")
public class Order {

	@TableId(type = IdType.ASSIGN_ID)
	Long orderId;

	double amount;

	Integer userId;

}
@Mapper
public interface OrderMapper extends BaseMapper<Order> {

}
  • 分表的測試
    @GetMapping("insert")
	@DS("sharding")
	public ResponseEntity test() {
		Order order = new Order();
		order.setAmount(100);
		order.setUserId(1);
		orderMapper.insert(order);
		return ResponseEntity.ok("success");
	}

  • 不進行分表的測試
    @GetMapping("insert-not-sharding")
	public ResponseEntity testNotSharding() {
		Order order = new Order();
		order.setAmount(101);
		order.setUserId(2);
		orderMapper.insert(order);
		return ResponseEntity.ok("success");
	}

作者:倉儲大叔,張占嶺,
榮譽:微軟MVP
QQ:853066980

支付寶掃一掃,為大叔打賞!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我們在學習 Java 基礎時就知道可以生成隨機數,可以為我們枯燥的學習增加那麼一丟丟的樂趣。本文就來介紹 Java 隨機數。 ...
  • ## 教程簡介 Ruby,一種簡單快捷的面向對象(面向對象程式設計)腳本語言,在20世紀90年代由日本人松本行弘(Yukihiro Matsumoto)開發,遵守GPL協議和Ruby License。它的靈感與特性來自於 Perl、Smalltalk、Eiffel、Ada以及 Lisp 語言。由 R ...
  • # 一、Java配置線程池 ## 1、線程池==分類==、其他 ### 1.1、分類 ==IO密集型 和 CPU密集型== 任務的特點不同,因此針對不同類型的任務,選擇不同類型的線程池可以獲得更好的性能表現。 #### 1.1. IO密集型任務 ​ IO密集型任務的特點是需要頻繁讀寫磁碟、網路或者其 ...
  • 一、準備一下 開發環境 Pycharm python 3.8 ffmpeg 模塊的使用 requests re subprocess 二、基本思路流程 1、明確需求 採集下破站視頻數據通過開發者工具進行抓包分析,分析破站視頻數據的來源。 開發者工具的使用 打開方式: 滑鼠右鍵點擊檢查選擇Networ ...
  • ## 前言 如題,這個小玩意,就是不限制你查的是哪張表,用的是什麼類。 我直接一把梭,嘎嘎給你一頓導出。 我知道,這是很多人都想過的, 至少我就收到很多人問過我這個類似的問題。 我也跟他們說了,但是他們就是不動手,其實真的很簡單。 不動手怎麼辦? 我出手唄。 不多說開搞 。 ## 正文 玩法很簡單。 ...
  • # 超輕量級 DynamicTableNameInnerInterceptor是mybatis-plug的一個攔截器插件,可以自己定義需要攔截的表單,然後對它進行加工,這時mybatis-plus就會把SQL代碼的表名加上你的這個裝飾。 # 封裝的思想 我們通常把mybatis做成一個包,公司其它同 ...
  • 用`markdown`寫文檔很方便,但是有個困擾的地方,就是標題的編號問題。 寫文檔的時候,經常會在中間插入新的標題和內容,所以手動管理編號的話,如果新的標題插在前面,則要調整後面所有的編號。 如果在文檔完成後再手動加上編號的話,不僅容易忘記, 而且有時候我們是在其他編輯器里編輯文檔再導出`mark ...
  • # 一、環境準備 Netty需要的運行環境很簡單,只有2個。 - JDK 1.8+ - Apache Maven 3.3.9+ # 二、Netty 客戶端/伺服器概覽 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/c49191e6ee6e448f8c525b450 ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...