第二章:Sharding-JDBC 快速入门

Sharding-JDBC快速入门
  • 需求说明

    • 本章节使用Sharding-JDBC演示单库分表初体验,完成对订单表的水平分表,通过快速入门程序的开发,快速体验Sharding-JDBC的使用方法
      • 人工创建两张表,t_order_1t_order_2,这两张表是订单表拆分后的表,通过Sharding-Jdbc向订单表插入数据,按照一定的分片规则,主键为偶数的进入t_order_1,另一部分数据进入t_order_2
      • 通过Sharding-Jdbc 查询数据,根据 SQL语句的内容从t_order_1或t_order_2查询数据。
        在这里插入图片描述
  • 环境搭建

    • 环境说明

      • 开发工具:IntelliJ IDEA
      • 数据库:MySQL-8.0.16-winx64
      • JDK:64位 jdk1.8.0
      • 应用框架:spring-boot-2.2.0.RELEASE,MyBatis-3.5.3
      • Sharding-JDBC:sharding-jdbc-spring-boot-starter-4.0.0-RC2
    • 创建数据库

      • 创建订单库order_db
        CREATE DATABASE `order_db` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
        
    • 创建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.apache.shardingsphere</groupId>
        	<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
        	<version>4.0.0-RC2</version>
        </dependency>
        
  • 编写sharding-jdbc配置

    • 分片规则配置
      • 分片规则配置是sharding-jdbc进行对分库分表操作的重要依据,配置内容包括:
        • 数据源
        • 主键生成策略
        • 分片策略等
    • 配置信息,见application.properties中配置
# Mybatis 配置
mybatis.mapper-locations = classpath:mapping/*Dao.xml
mybatis.type-aliases-package = com.shair.domain

#sharding-jdbc分片规则配置
#数据源
spring.shardingsphere.datasource.names = m1
spring.shardingsphere.datasource.m1.type = com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.m1.driver-class-name = com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.jdbcUrl = jdbc:mysql://127.0.0.1:3306/order_db?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false
spring.shardingsphere.datasource.m1.username = root
spring.shardingsphere.datasource.m1.password = root

# 指定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

  • 编写程序
# OrderDao
@Mapper
public interface OrderDao {

    int insert(Order record);
}

# OrderDao.xml
<insert id="insert" parameterType="com.shair.domain.Order">
    INSERT INTO t_order (price, user_id, status)
    VALUES (#{price,jdbcType=DECIMAL}, #{userId,jdbcType=BIGINT}, #{status,jdbcType=VARCHAR})
</insert>

  • 测试代码
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {

    @Autowired
    private OrderDao orderDao;
    
    @Test
    public void testInsertOrder() {
        for (int i = 0; i < 10; i++) {
            Order order = new Order();
            order.setPrice(new BigDecimal((i + 1) * 5));
            order.setUserId(1L);
            order.setStatus("SUCCESS");
            orderDao.insert(order);
        }
    }
  • 测试数据
    • 执行 testInsertOrder
    • 通过日志可以发现:
      • order_id为奇数的被插入到 t_order_2
      • order_id为偶数的被插入到 t_order_1
2019-10-27 16:06:34.035 [main] INFO  ShardingSphere-SQL - Actual SQL: m1 ::: INSERT INTO t_order_1 (price, user_id, status, order_id)
    VALUES (?, ?, ?, ?) ::: [20, 1, SUCCESS, 395246018112782336]
2019-10-27 16:06:34.046 [main] INFO  ShardingSphere-SQL - Actual SQL: m1 ::: INSERT INTO t_order_2 (price, user_id, status, order_id)
    VALUES (?, ?, ?, ?) ::: [25, 1, SUCCESS, 395246018154725377]

  • 流程分析
    • Sharding-JDBC在拿到用户要执行的sql后,执行以下步骤
      • 解析sql,获取片键值,在本例中是order_id
      • Sharding-JDBC通过规则配置 t_order_$->{order_id % 2 + 1},知道了当order_id为偶数时,应该往t_order_1表插数据,为奇数时,往t_order_2插数据
      • 于是Sharding-JDBC根据order_id的值改写sql语句,改写后的SQL语句是真实所要执行的SQL语句
      • 执行改写后的真实sql语句
      • 将所有真正执行sql的结果进行汇总合并,返回
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值