一、ShardingSphere 是什么?
Apache ShardingSphere 是一套开源的分布式数据库解决方案组成的生态圈,它由 JDBC、Proxy 和 Sidecar(规划中)这 3 款既能够独立部署,又支持混合部署配合使用的产品组成。 它们均提供标准化的数据水平扩展、分布式事务和分布式治理等功能,可适用于如 Java 同构、异构语言、云原生等各种多样化的应用场景。
Apache ShardingSphere 旨在充分合理地在分布式的场景下利用关系型数据库的计算和存储能力,而并非实现一个全新的关系型数据库。 关系型数据库当今依然占有巨大市场份额,是企业核心系统的基石,未来也难于撼动,因此 ShardingSphere 更加注重在原有基础上提供增量,而非颠覆。
Apache ShardingSphere 5.x 版本开始致力于可插拔架构,项目的功能组件能够灵活的以可插拔的方式进行扩展。 目前,数据分片、读写分离、数据加密、影子库压测等功能,以及 MySQL、PostgreSQL、SQLServer、Oracle 等 SQL 与协议的支持,均通过插件的方式织入项目。 开发者能够像使用积木一样定制属于自己的独特系统。Apache ShardingSphere 目前已提供数十个 SPI 作为系统的扩展点,仍在不断增加中。
ShardingSphere 已于2020年4月16日成为 Apache 软件基金会的顶级项目。
二、创建项目集成 ShardingSphere 实现分库分表
1.项目说明
新建 Spring Initializr 项目 sharding,项目下新建controller、entity、mapper、service类。创建 MySQL 数据库 shop 和 shop_1,两个数据库下均创建 t_order_0 和 t_order_1 表。项目实现按 order 表主键 order_id 取模存储,0 在 shop 库 t_order_0 表,1 在 shop_1 库 t_order_1 表。
项目目录结构:
2.创建 Spring Initializr 项目 sharding
(1).添加依赖
添加依赖,如果已按截图操作,pom.xml 还需引入 mybatis-plus-boot-starter 和 sharding-jdbc-spring-boot-starter 依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="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.0 https://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.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.chaoyue</groupId>
<artifactId>mybatisplus</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatisplus</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
(2).添加配置
application.yml 文件中添加如下配置:
server:
port: 8080
spring:
shardingsphere:
# 打开sql控制台输出日志
props:
sql:
show: true
datasource:
names: ds-master-0,ds-master-1
# 第一个数据源
ds-master-0:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/shop?characterEncoding=utf-8&useSSL=false
username: root
password: 123456
# 第二个数据源
ds-master-1:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/shop_1?characterEncoding=utf-8&useSSL=false
username: root
password: 123456
# 配置 order 表规则
sharding:
tables:
t_order:
actual-data-nodes: ds-master-$->{0..1}.t_order_$->{0..1}
# 配置分表策略,主键取模,0在0表,1在1表
table-strategy:
inline:
# 分片列名称
sharding-column: order_id
# 分片算法行表达式
algorithm-expression: t_order_$->{order_id % 2}
# 主键策略:雪花算法
key-generator:
column: order_id
type: SNOWFLAKE
# 配置分库策略,主键取模0在0库,1在1库
default-database-strategy:
inline:
sharding-column: order_id
#分片算法行表达式
algorithm-expression: ds-master-$->{order_id % 2}
main:
allow-bean-definition-overriding: true
management:
endpoints:
web:
exposure:
include: '*'
mybatis-plus:
type-aliases-package: com.chaoyue.sharding.mapper
mapper-locations: classpath:/mapper/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
(3).新建实体类 Order
为减少不必要的代码,引入 lombok 依赖。实体类代码如下:
package com.chaoyue.sharding.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
@Data
@TableName("t_order")
public class Order {
private Long orderId; // 订单 id
private Long userId; // 用户 id
private String areaCode; // 区域编码
private String orderNo; // 订单号
private Date createDate; // 创建时间
private Date updateDate; // 修改时间
}
(4).新建 Mapper 接口类 OrderMapper
package com.chaoyue.sharding.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chaoyue.sharding.entity.Order;
import org.springframework.stereotype.Repository;
@Repository
public interface OrderMapper extends BaseMapper<Order> {
}
(5).新建服务接口类 OrderService
package com.chaoyue.sharding.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.chaoyue.sharding.entity.Order;
public interface OrderService extends IService<Order> {
}
(6).新建服务实现类 OrderServiceImpl
package com.chaoyue.sharding.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chaoyue.sharding.entity.Order;
import com.chaoyue.sharding.mapper.OrderMapper;
import com.chaoyue.sharding.service.OrderService;
import org.springframework.stereotype.Service;
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order>implements OrderService {
}
(7).新建控制类 OrderController
package com.chaoyue.sharding.controller;
import com.chaoyue.sharding.entity.Order;
import com.chaoyue.sharding.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
@RestController
@RequestMapping("/user")
public class OrderController {
@Autowired
private OrderService orderService;
@RequestMapping("/getAll")
public String getAll() {
List<Order> list = orderService.list();
return list.toString();
}
@RequestMapping("/insert/{orderId}")
public String insert(@PathVariable Long orderId) {
Order order = new Order();
order.setOrderId(orderId);
order.setAreaCode("100000");
order.setOrderNo("dd100000");
order.setUserId(1L);
order.setCreateDate(new Date());
order.setUpdateDate(new Date());
orderService.save(order);
return getAll();
}
}
(8).启动类添加注解
启动类添加注解 @MapperScan(“com.chaoyue.mybatisplus.mapper”)
package com.chaoyue.sharding;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.chaoyue.sharding.mapper")
public class ShardingApplication {
public static void main(String[] args) {
SpringApplication.run(ShardingApplication.class, args);
}
}
3.创建数据库 shop、shop_1 和数据表 t_order_0、t_order_1
-- ----------------------------
-- Table structure for t_order_0
-- ----------------------------
DROP TABLE IF EXISTS `t_order_0`;
CREATE TABLE `t_order_0` (
`order_id` bigint(20) NOT NULL COMMENT '订单id',
`user_id` bigint(20) NULL DEFAULT NULL COMMENT '用户id',
`area_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '区域编码',
`order_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '订单号',
`create_date` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_date` datetime NULL DEFAULT NULL COMMENT '修改时间',
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '订单表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for t_order_1
-- ----------------------------
DROP TABLE IF EXISTS `t_order_1`;
CREATE TABLE `t_order_1` (
`order_id` bigint(20) NOT NULL COMMENT '订单id',
`user_id` bigint(20) NULL DEFAULT NULL COMMENT '用户id',
`area_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '区域编码',
`order_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '订单号',
`create_date` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_date` datetime NULL DEFAULT NULL COMMENT '修改时间',
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '订单表' ROW_FORMAT = Dynamic;
4.启动服务并测试
启动服务后,浏览器输入:http://localhost:8080/user/insert/5,(insert 后的 id 连接输入1-5)返回:
查看数据库。shop_1 的 t_order_1 显示:
shop 的 t_order_0 显示:
PS:shardingsphere 中文网链接:
https://shardingsphere.apache.org/index_zh.html
--end--