1. 程式人生 > 實用技巧 >輕量級的資料庫中介軟體解決了SpringBoot中分庫分表問題

輕量級的資料庫中介軟體解決了SpringBoot中分庫分表問題

一、 Sharding-jdbc簡介

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

官方文件地址:

https://shardingsphere.apache.org/document/current/cn/overview/

本文demo實現了分庫分表功能。

作者能力有限,如有錯誤,歡迎各位在評論中指出。不勝感激!

二、專案結構

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

POM.xml檔案如下:

<?xmlversion="1.0"encoding="UTF-8"?>
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/><!--lookupparentfromrepository-->
</parent>
<groupId>com.macky</groupId>
<artifactId>spring-boot-shardingjdbc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-shardingjdbc</name>
<description>Demoprojectforspring-boot-shardingjdbc</description>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--Mybatis-Plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.1</version>
</dependency>
<!--shardingspherestart-->
<!--forspringboot-->
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<!--forspringnamespace-->
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-namespace</artifactId>
<version>3.1.0</version>
</dependency>
<!--shardingsphereend-->
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

實體類以書本為例

packagecom.macky.springbootshardingjdbc.entity;

importcom.baomidou.mybatisplus.annotation.TableName;
importcom.baomidou.mybatisplus.extension.activerecord.Model;
importgroovy.transform.EqualsAndHashCode;
importlombok.Data;
importlombok.experimental.Accessors;

/**
*@authorMacky
*@TitleclassBook
*@Description:書籍是實體類
*/
@Data
@EqualsAndHashCode(callSuper=true)
@Accessors(chain=true)
@TableName("book")
publicclassBookextendsModel<Book>{
privateintid;
privateStringname;
privateintcount;
}

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

packagecom.macky.springbootshardingjdbc.controller;

importcom.macky.springbootshardingjdbc.entity.Book;
importcom.macky.springbootshardingjdbc.service.BookService;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.web.bind.annotation.*;

importjava.util.List;

/**
*@authorMacky
*@TitleclassBookController
*@Description:TODO
*/
@RestController
publicclassBookController{

@Autowired
BookServicebookService;

@RequestMapping(value="/book",method=RequestMethod.GET)
publicList<Book>getItems(){
returnbookService.getBookList();
}

@RequestMapping(value="/book",method=RequestMethod.POST)
publicBooleansaveItem(Bookbook){
returnbookService.save(book);
}
}

BookServiceImpl.java

packagecom.macky.springbootshardingjdbc.service.impl;

importcom.baomidou.mybatisplus.core.toolkit.Wrappers;
importcom.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
importcom.macky.springbootshardingjdbc.entity.Book;
importcom.macky.springbootshardingjdbc.mapper.BookMapper;
importcom.macky.springbootshardingjdbc.service.BookService;
importorg.springframework.stereotype.Service;

importjava.util.List;

/**
*@authorMacky
*@TitleclassBookServiceImpl
*@Description:TODO
*@date2019/7/1220:47
*/
@Service
publicclassBookServiceImplextendsServiceImpl<BookMapper,Book>implementsBookService{

@Override
publicList<Book>getBookList(){
returnbaseMapper.selectList(Wrappers.<Book>lambdaQuery());
}

@Override
publicbooleansave(Bookbook){
returnsuper.save(book);
}
}

BookMapper.java

packagecom.macky.springbootshardingjdbc.mapper;

importcom.baomidou.mybatisplus.core.mapper.BaseMapper;
importcom.macky.springbootshardingjdbc.entity.Book;

/**
*@authorMacky
*@TitleclassBookMapper
*@Description:TODO
*@date2019/7/1220:46
*/
publicinterfaceBookMapperextendsBaseMapper<Book>{
}

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

#建立資料庫表資料
CREATEDATABASEIFNOTEXISTS`db0`;
USE`db0`;
DROPTABLEIFEXISTS`book_0`;
CREATETABLE`book_0`(
`id`INT(11)NOTNULL,
`name`VARCHAR(255)DEFAULTNULL,
`count`INT(11)DEFAULTNULL,
PRIMARYKEY(`id`)
)ENGINE=INNODBDEFAULTCHARSET=utf8mb4;
DROPTABLEIFEXISTS`book_1`;
CREATETABLE`book_1`(
`id`INT(11)NOTNULL,
`name`VARCHAR(255)DEFAULTNULL,
`count`INT(11)DEFAULTNULL,
PRIMARYKEY(`id`)
)ENGINE=INNODBDEFAULTCHARSET=utf8mb4;

CREATEDATABASEIFNOTEXISTS`db1`;
USE`db1`;
DROPTABLEIFEXISTS`book_0`;
CREATETABLE`book_0`(
`id`INT(11)NOTNULL,
`name`VARCHAR(255)DEFAULTNULL,
`count`INT(11)DEFAULTNULL,
PRIMARYKEY(`id`)
)ENGINE=INNODBDEFAULTCHARSET=utf8mb4;
DROPTABLEIFEXISTS`book_1`;
CREATETABLE`book_1`(
`id`INT(11)NOTNULL,
`name`VARCHAR(255)DEFAULTNULL,
`count`INT(11)DEFAULTNULL,
PRIMARYKEY(`id`)
)ENGINE=INNODBDEFAULTCHARSET=utf8mb4;

CREATEDATABASEIFNOTEXISTS`db2`;
USE`db2`;
DROPTABLEIFEXISTS`book_0`;
CREATETABLE`book_0`(
`id`INT(11)NOTNULL,
`name`VARCHAR(255)DEFAULTNULL,
`count`INT(11)DEFAULTNULL,
PRIMARYKEY(`id`)
)ENGINE=INNODBDEFAULTCHARSET=utf8mb4;
DROPTABLEIFEXISTS`book_1`;
CREATETABLE`book_1`(
`id`INT(11)NOTNULL,
`name`VARCHAR(255)DEFAULTNULL,
`count`INT(11)DEFAULTNULL,
PRIMARYKEY(`id`)
)ENGINE=INNODBDEFAULTCHARSET=utf8mb4;

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

#資料來源db0,db1,db2
sharding.jdbc.datasource.names=db0,db1,db2
#第一個資料庫
sharding.jdbc.datasource.db0.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.db0.driver-class-name=com.mysql.cj.jdbc.Driver
sharding.jdbc.datasource.db0.jdbc-url=jdbc:mysql://localhost:3306/db0?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
sharding.jdbc.datasource.db0.username=root
sharding.jdbc.datasource.db0.password=Aa123456

#第二個資料庫
sharding.jdbc.datasource.db1.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.db1.driver-class-name=com.mysql.cj.jdbc.Driver
sharding.jdbc.datasource.db1.jdbc-url=jdbc:mysql://localhost:3306/db1?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
sharding.jdbc.datasource.db1.username=root
sharding.jdbc.datasource.db1.password=Aa123456

#第三個資料庫
sharding.jdbc.datasource.db2.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.db2.driver-class-name=com.mysql.cj.jdbc.Driver
sharding.jdbc.datasource.db2.jdbc-url=jdbc:mysql://localhost:3306/db2?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
sharding.jdbc.datasource.db2.username=root
sharding.jdbc.datasource.db2.password=Aa123456

#水平拆分的資料庫(表)配置分庫+分表策略行表示式分片策略
#分庫策略
sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=id
sharding.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..1}
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%2}

#主鍵UUID18位數如果是分散式還要進行一個設定防止主鍵重複
#sharding.jdbc.config.sharding.tables.user.key-generator-column-name=id

#列印執行的資料庫以及語句
sharding.jdbc.config.props..sql.show=true
spring.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搭建指南,如需深入理解,還請移步至官方文件。