Springboot整合 Sharding-JDBC + Mybatis-Plus實現分庫分表(原始碼)

# Sharding-jdbc簡介

Sharding-jdbc是開源的資料庫操作中介軟體;定位為輕量級Java框架,在Java的JDBC層提供的額外服務。它使用客戶端直連資料庫,以jar包形式提供服務,無需額外部署和依賴,可理解為增強版的JDBC驅動,完全相容JDBC和各種ORM框架。

官方文件地址:https://shardingsphere。apache。org/document/current/cn/overview/

本文demo實現了分庫分表功能。如有錯誤,歡迎各位在評論中指出。不勝感激!

# 專案結構

首先建立一個一般的Spring boot專案,專案採用三層架構,結構圖如下:

Springboot整合 Sharding-JDBC + Mybatis-Plus實現分庫分表(原始碼)

POM。xml檔案如下:

<?xml version=“1。0” encoding=“UTF-8”?> 4。0。0 org。springframework。boot spring-boot-starter-parent 2。1。6。RELEASE <!—— lookup parent from repository ——> com。macky spring-boot-shardingjdbc 0。0。1-SNAPSHOT spring-boot-shardingjdbc Demo project for spring-boot-shardingjdbc 1。8 org。springframework。boot spring-boot-starter-web org。springframework。boot spring-boot-starter-test test <!——mysql——> mysql mysql-connector-java runtime <!——Mybatis-Plus——> com。baomidou mybatis-plus-boot-starter 3。1。1 <!——shardingsphere start——> <!—— for spring boot ——> io。shardingsphere sharding-jdbc-spring-boot-starter 3。1。0 <!—— for spring namespace ——> io。shardingsphere sharding-jdbc-spring-namespace 3。1。0 <!——shardingsphere end——> <!——lombok——> org。projectlombok lombok org。springframework。boot spring-boot-maven-plugin

實體類以書本為例

package com。macky。springbootshardingjdbc。entity;import com。baomidou。mybatisplus。annotation。TableName;import com。baomidou。mybatisplus。extension。activerecord。Model;import groovy。transform。EqualsAndHashCode;import lombok。Data;import lombok。experimental。Accessors;/** * @author Macky * @Title class Book * @Description: 書籍是實體類 * @date 2019/7/13 15:23 */@Data@EqualsAndHashCode(callSuper = true)@Accessors(chain = true)@TableName(“book”)public class Book extends Model { private int id; private String name; private int count;}

開放儲存和查詢兩個介面,程式碼如下:

package com。macky。springbootshardingjdbc。controller;import com。macky。springbootshardingjdbc。entity。Book;import com。macky。springbootshardingjdbc。service。BookService;import org。springframework。beans。factory。annotation。Autowired;import org。springframework。web。bind。annotation。*;import java。util。List;/** * @author Macky * @Title class BookController * @Description: TODO * @date 2019/7/12 20:53 */@RestControllerpublic class BookController { @Autowired BookService bookService; @RequestMapping(value = “/book”, method = RequestMethod。GET) public List getItems(){ return bookService。getBookList(); } @RequestMapping(value = “/book”,method = RequestMethod。POST) public Boolean saveItem(Book book){ return bookService。save(book); }}

BookServiceImpl。java

package com。macky。springbootshardingjdbc。service。impl;import com。baomidou。mybatisplus。core。toolkit。Wrappers;import com。baomidou。mybatisplus。extension。service。impl。ServiceImpl;import com。macky。springbootshardingjdbc。entity。Book;import com。macky。springbootshardingjdbc。mapper。BookMapper;import com。macky。springbootshardingjdbc。service。BookService;import org。springframework。stereotype。Service;import java。util。List;/** * @author Macky * @Title class BookServiceImpl * @Description: TODO * @date 2019/7/12 20:47 */@Servicepublic class BookServiceImpl extends ServiceImpl implements BookService { @Override public List getBookList() { return baseMapper。selectList(Wrappers。lambdaQuery()); } @Override public boolean save(Book book) { return super。save(book); }}

BookMapper。java

package com。macky。springbootshardingjdbc。mapper;import com。baomidou。mybatisplus。core。mapper。BaseMapper;import com。macky。springbootshardingjdbc。entity。Book;/** * @author Macky * @Title class BookMapper * @Description: TODO * @date 2019/7/12 20:46 */public interface BookMapper extends BaseMapper {}

建立資料庫表,DDL語句如下

建立資料庫表資料CREATE DATABASE IF NOT EXISTS `db0`;USE `db0`;DROP TABLE IF EXISTS `book_0`;CREATE TABLE `book_0` ( `id` INT ( 11 ) NOT NULL, `name` VARCHAR ( 255 ) DEFAULT NULL, `count` INT ( 11 ) DEFAULT NULL, PRIMARY KEY ( `id` )) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;DROP TABLE IF EXISTS `book_1`;CREATE TABLE `book_1` ( `id` INT ( 11 ) NOT NULL, `name` VARCHAR ( 255 ) DEFAULT NULL, `count` INT ( 11 ) DEFAULT NULL, PRIMARY KEY ( `id` )) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;CREATE DATABASE IF NOT EXISTS `db1`;USE `db1`;DROP TABLE IF EXISTS `book_0`;CREATE TABLE `book_0` ( `id` INT ( 11 ) NOT NULL, `name` VARCHAR ( 255 ) DEFAULT NULL, `count` INT ( 11 ) DEFAULT NULL, PRIMARY KEY ( `id` )) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;DROP TABLE IF EXISTS `book_1`;CREATE TABLE `book_1` ( `id` INT ( 11 ) NOT NULL, `name` VARCHAR ( 255 ) DEFAULT NULL, `count` INT ( 11 ) DEFAULT NULL, PRIMARY KEY ( `id` )) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;CREATE DATABASE IF NOT EXISTS `db2`;USE `db2`;DROP TABLE IF EXISTS `book_0`;CREATE TABLE `book_0` ( `id` INT ( 11 ) NOT NULL, `name` VARCHAR ( 255 ) DEFAULT NULL, `count` INT ( 11 ) DEFAULT NULL, PRIMARY KEY ( `id` )) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;DROP TABLE IF EXISTS `book_1`;CREATE TABLE `book_1` ( `id` INT ( 11 ) NOT NULL, `name` VARCHAR ( 255 ) DEFAULT NULL, `count` INT ( 11 ) DEFAULT NULL, PRIMARY KEY ( `id` )) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;

配置分庫分表策略application。properties:

> 推薦一個艿艿寫的 3000+ Star 的 SpringCloud Alibaba 電商開源專案的倉庫:# 資料來源 db0,db1,db2sharding。jdbc。datasource。names=db0,db1,db2# 第一個資料庫sharding。jdbc。datasource。db0。type=com。zaxxer。hikari。HikariDataSourcesharding。jdbc。datasource。db0。driver-class-name=com。mysql。cj。jdbc。Driversharding。jdbc。datasource。db0。jdbc-url=jdbc:mysql://localhost:3306/db0?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTCsharding。jdbc。datasource。db0。username=rootsharding。jdbc。datasource。db0。password=Aa123456# 第二個資料庫sharding。jdbc。datasource。db1。type=com。zaxxer。hikari。HikariDataSourcesharding。jdbc。datasource。db1。driver-class-name=com。mysql。cj。jdbc。Driversharding。jdbc。datasource。db1。jdbc-url=jdbc:mysql://localhost:3306/db1?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTCsharding。jdbc。datasource。db1。username=rootsharding。jdbc。datasource。db1。password=Aa123456# 第三個資料庫sharding。jdbc。datasource。db2。type=com。zaxxer。hikari。HikariDataSourcesharding。jdbc。datasource。db2。driver-class-name=com。mysql。cj。jdbc。Driversharding。jdbc。datasource。db2。jdbc-url=jdbc:mysql://localhost:3306/db2?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTCsharding。jdbc。datasource。db2。username=rootsharding。jdbc。datasource。db2。password=Aa123456# 水平拆分的資料庫(表) 配置分庫 + 分表策略 行表示式分片策略# 分庫策略sharding。jdbc。config。sharding。default-database-strategy。inline。sharding-column=idsharding。jdbc。config。sharding。default-database-strategy。inline。algorithm-expression=db$->{id % 3}# 分表策略 其中book為邏輯表 分表主要取決於id行sharding。jdbc。config。sharding。tables。book。actual-data-nodes=db$->{0。。2}。book_$->{0。。2}sharding。jdbc。config。sharding。tables。book。table-strategy。inline。sharding-column=count# 分片演算法表示式sharding。jdbc。config。sharding。tables。book。table-strategy。inline。algorithm-expression=book_$->{count % 3}# 主鍵 UUID 18位數 如果是分散式還要進行一個設定 防止主鍵重複#sharding。jdbc。config。sharding。tables。user。key-generator-column-name=id# 列印執行的資料庫以及語句sharding。jdbc。config。props。。sql。show=truespring。main。allow-bean-definition-overriding=true#讀寫分離sharding。jdbc。datasource。dsmaster =

介面測試使用postman

示例:

GET請求————>http://localhost:8080/book

POST請求:————->http://localhost:8080/book?id=1&name=java程式設計思想&count=8

demo的github地址:

https://github。com/Macky-He/spring-boot——shardingsphere-examples

如各位覺得有幫助的話,還請給個star鼓勵鼓勵博主,謝謝!

# 總結

分庫分表實現按照官方文件做一個demo是第一步,如需深入還需要研究原始碼,研究架構,研究思想;此文僅作為入門demo搭建指南,如需深入理解,還請移步至官方文件。

參考資料

https://shardingsphere。apache。org/document/current/cn/manual/sharding-jdbc/usage/sharding/