需求说明
本章节使用Sharding-JDBC完成对订单表的水平分表,通过快速入门程序的开发,快速体验Sharding-JDBC的使用方法。
人工创建两张表,t_order_1和t_order_2,这两张表是订单表拆分后的表,通过Sharding-Jdbc向订单表插入数据,按照一定的分片规则,主键为偶数的进入t_order_1,另一部分数据进入t_order_2,通过Sharding-Jdbc 查询数据,根据 SQL语句的内容从t_order_1或t_order_2查询数据。
环境搭建
环境说明
- 操作系统:Win10
- 数据库:MySQL-5.7.25
- JDK:64位 jdk1.8.0_201
- 应用框架:spring-boot-2.1.3.RELEASE,Mybatis3.5.0
- Sharding-JDBC:sharding-jdbc-spring-boot-starter-4.0.0-RC1
创建数据库
创建订单库order_db
CREATE DATABASE `order_db` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
在order_db中创建t_order_1、t_order_2表
DROP TABLE IF EXISTS `t_order_1`; CREATE TABLE `t_order_1` ( `order_id` bigint(20) NOT NULL COMMENT '订单id', `price` decimal(10, 2) NOT NULL COMMENT '订单价格', `user_id` bigint(20) NOT NULL COMMENT '下单用户id', `status` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单状态', PRIMARY KEY (`order_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
DROP TABLE IF EXISTS `t_order_2`; CREATE TABLE `t_order_2` ( `order_id` bigint(20) NOT NULL COMMENT '订单id', `price` decimal(10, 2) NOT NULL COMMENT '订单价格', `user_id` bigint(20) NOT NULL COMMENT '下单用户id', `status` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单状态', PRIMARY KEY (`order_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
引入maven依赖
引入 sharding-jdbc和SpringBoot整合的Jar包:
<dependency> <groupId>org.mybatis.spring.bootgroupId> <artifactId>mybatis-spring-boot-starterartifactId> <version>2.0.0version> dependency> <dependency> <groupId>org.mybatisgroupId> <artifactId>mybatisartifactId> <version>3.4.6version> dependency> <dependency> <groupId>com.alibabagroupId> <artifactId>druid-spring-boot-starterartifactId> <version>1.1.16version> dependency> <dependency> <groupId>mysqlgroupId> <artifactId>mysql-connector-javaartifactId> <version>5.1.47version> dependency> <dependency> <groupId>org.apache.shardingspheregroupId> <artifactId>sharding-jdbc-spring-boot-starterartifactId> <version>4.0.0-RC1version> dependency>
编写程序
分片规则配置
分片规则配置是sharding-jdbc进行对分库分表操作的重要依据,配置内容包括:数据源、主键生成策略、分片策略等。
在application.properties中配置
spring.main.allow-bean-definition-overriding=true mybatis.configuration.map-underscore-to-camel-case=true #sharding-jdbc分片规则配置 #数据源 spring.shardingsphere.datasource.names=m1 spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.jdbc.Driver spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/order_db?useUnicode=true spring.shardingsphere.datasource.m1.username=root spring.shardingsphere.datasource.m1.password=123456 # 指定t_order表的数据分布情况,配置数据节点 m1.t_order_1,m1.t_order_2 spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=m1.t_order_$->{1..2} # 指定t_order表的主键生成策略为SNOWFLAKE spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE # 指定t_order表的分片策略,分片策略包括分片键和分片算法 spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{order_id % 2 + 1} # 打开sql输出日志 spring.shardingsphere.props.sql.show=true
- 首先定义数据源m1,并对m1进行实际的参数配置。
- 指定t_order表的数据分布情况,他分布在m1.t_order_1,m1.t_order_2
- 指定t_order表的主键生成策略为SNOWFLAKE,SNOWFLAKE是一种分布式自增算法,保证id全局唯一
- 定义t_order分片策略,order_id为偶数的数据落在t_order_1,为奇数的落在t_order_2,分表策略的表达式为t_order_$->{order_id % 2 + 1}
数据操作
package com.example.demo.dao; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.util.List; import java.util.Map; /** * Created by Administrator. */ @Mapper @Component public interface OrderDao { /** * 插入订单 * * @param price * @param userId * @param status * @return */ @Insert("insert into t_order(price,user_id,status)values(#{price},#{userId},#{status})") int insertOrder(@Param("price") BigDecimal price, @Param("userId") Long userId, @Param("status") String status); /** * 根据id列表查询订单 * * @param orderIds * @return */ @Select("") List
测试
package com.example.demo.dao; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Map; @SpringBootTest public class OrderDaoTest { @Autowired private OrderDao orderDao; @Test public void testInsertOrder() { for (int i = 0; i < 10; i++) { orderDao.insertOrder(new BigDecimal((i + 1) * 5), 1L, "WAIT_PAY"); } } @Test public void testSelectOrderbyIds() { Listids = new ArrayList<>(); ids.add(481164813670547456L); ids.add(481164813368557569L); List
执行testInsertOrder:
通过日志可以发现order_id为奇数的被插入到t_order_2表,为偶数的被插入到t_order_1表,达到预期目标。
执行testSelectOrderbyIds:
通过日志可以发现,根据传入order_id的奇偶不同,sharding-jdbc分别去不同的表检索数据,达到预期目标