最详细的分库分表Demo—springboot_shardingjdbc_mybatis

13 篇文章 1 订阅
10 篇文章 1 订阅

分库分表 — Shardingjdbc

分库分表:分库分表

为什么分表? 肯定是因为需要
怎么进行分表?垂直分表和水平分表
什么是垂直分表?如果表过大,垂直分表就是按照业务角度将大列分为几个表,划分的原则一般是频繁变化的分为一个表,不频繁变化的,尤其大字段,如text和blob字段这种影响io性能的划分为另外一个表中,这样就实现了垂直分表。如下图:

在这里插入图片描述

什么是水平分表?就是将数据根据策略分到不同的表中,从而使数据均匀的分布在不同的数据库和表中,也是最常见的分表方式。如下就是将一个表分为四个表:

将ds库中的order表分成了ds0库的order0和order1以及ds1库的order0和order1表,

分库分表的策略是根据数据的sharding_db_id字段与2取余来决定放到ds0还是ds1,

如果取余是0就放到ds0,如果取余是1就放到ds1.

同理分表也是采用相同的策略,只不过根据列shardind_table_id与2取余。

这样一行数据就确定了这条数据应该放到哪个库那个表中。从而实现数据的分库分表。

同时,为了保证全局的order数据在不同的库和表中保持全局唯一,我们用key_id字段

存储雪花算法生成的全局id。

在这里插入图片描述

下面就给大家展示一下springboot_shardingjdbc_mybatis实现分库分表
先创建数据库和数据表
CREATE DATABASE ds_0; #创建数据库ds_0

DROP TABLE IF EXISTS `order0`; #创建表order0
CREATE TABLE `order0`  (
                           `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
                           `sharding_db_id` int(0) NOT NULL COMMENT '分库用的ID',
                           `sharding_table_id` int(0) NOT NULL COMMENT '分表用的ID',
                           `key_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '全局id',
                           PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `order1`; #创建表order1
CREATE TABLE `order1`  (
                           `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
                           `sharding_db_id` int(0) NOT NULL COMMENT '分库用的ID',
                           `sharding_table_id` int(0) NOT NULL COMMENT '分表用的ID',
                           `key_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '全局id',
                           PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;


CREATE DATABASE ds_1; #创建数据库ds_1

DROP TABLE IF EXISTS `order0`; #创建表order0
CREATE TABLE `order0`  (
                           `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
                           `sharding_db_id` int(0) NOT NULL COMMENT '分库用的ID',
                           `sharding_table_id` int(0) NOT NULL COMMENT '分表用的ID',
                           `key_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '全局id',
                           PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;


DROP TABLE IF EXISTS `order1`; #创建表order1
CREATE TABLE `order1`  (
                           `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
                           `sharding_db_id` int(0) NOT NULL COMMENT '分库用的ID',
                           `sharding_table_id` int(0) NOT NULL COMMENT '分表用的ID',
                           `key_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '全局id',
                           PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
pom.xml的主要依赖内容
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.23</version>
        </dependency>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.1.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>RELEASE</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

    </dependencies>
Mybatis 数据对象 Domain
/*
* 永旺数字科技有限公司版权所有.
*/

package com.example.demo.mapper.domain;

/**
 * (与数据库表字段一一对应的实体类,公有字段继承至父类)
 *
 * @author 今天例外
 * @version 1.0.0
 * @date 2021-04-07
 */
public class OrderDomain {
    private static final long serialVersionUID = 1L;
    /**
     * 主键ID
     */
    private Long Id;

    private Long shardingDbId;

    private Long shardingTableId;

    public OrderDomain(Long shardingDbId, Long shardingTableId) {
        this.shardingDbId = shardingDbId;
        this.shardingTableId = shardingTableId;
    }

    public OrderDomain() {
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public Long getShardingDbId() {
        return shardingDbId;
    }

    public void setShardingDbId(Long shardingDbId) {
        this.shardingDbId = shardingDbId;
    }

    public Long getShardingTableId() {
        return shardingTableId;
    }

    public void setShardingTableId(Long shardingTableId) {
        this.shardingTableId = shardingTableId;
    }

    public Long getId() {
        return Id;
    }

    public void setId(Long id) {
        Id = id;
    }
}
Mybatis XML文件

注意这里的表名用的是配置分表时的抽象表名,而不是具体的表名

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.OrderMapper">
   <!-- 通用查询映射结果 -->
   <resultMap id="BaseResultMap" type="com.example.demo.mapper.domain.OrderDomain">
      <id column="id" property="id" />
      <result column="order_id" property="orderId" />
   </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
    id,
    order_id
    </sql>

    <!--基础CRUD、分页、列表部分 begin-->
    <insert id="save" parameterType="com.example.demo.mapper.domain.OrderDomain"
            keyProperty="id" useGeneratedKeys="true">
            <!--注意这里的表名用的是配置分表时的抽象表名,而不是具体的表名-->
        insert into t_order
        (
            id,
            sharding_db_id,
            sharding_table_id
        )
        values
        (
            #{id},
            #{shardingDbId},
            #{shardingTableId}
        )
    </insert>

</mapper>
Mybatis Mapper文件
/*
* 永旺数字科技有限公司版权所有.
*/

package com.example.demo.mapper;

import com.example.demo.mapper.domain.OrderDomain;
import org.apache.ibatis.annotations.Mapper;

/**
 * Mapper接口
 *
 * @author 今天例外
 * @version 1.0.0
 * @date 2021-04-07
 */
@Mapper
public interface OrderMapper {

    void save(OrderDomain orderDomain);

}
property.yaml内容
mybatis:
  mapper-locations: classpath:mapper/*.xml

#sharding-jdbc配置
spring:
  shardingsphere:
    datasource:
      names: ds0,ds1 # 兹定于虚拟库名
      # master数据源配置
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8&serverTimezone=UTC
        username: root #你的账号
        password: 123456 #你的密码
      ds1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/ds_1?characterEncoding=utf-8&serverTimezone=UTC
        username: root #你的账号
        password: 123456 #你的密码

    # 单库分表 这里只定义一个库ds1
    sharding:
      tables:
        t_order: #自定义虚拟表名 但是在mapper.xml中 操作表的时候 要用这个虚拟表名
          actual-data-nodes: ds$->{0..1}.order$->{0..1}
          databaseStrategy: #分库策略
            inline:
              shardingColumn: sharding_db_id #分库用的列名(真实列名)
              algorithmExpression: ds${sharding_db_id % 2} #分库算法,根据上面的列里面的数据计算分到哪个库
          table-strategy: #分表策略
            inline:
              sharding-column: sharding_table_id #分表用的列名(真实列名)
              algorithm-expression: order$->{sharding_table_id % 2} #分表算法,根据上面的列里面的数据计算分到哪个表
          keyGenerator:
            type: SNOWFLAKE #雪花算法
            column: key_id #用雪花算法生成全局(所有库所有order表)唯一
props:
  sql.show: true
如果你想直接测试的话 你可以用我这个单元测试
package com.example.demo;

import com.example.demo.mapper.OrderMapper;
import com.example.demo.mapper.domain.OrderDomain;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.sql.SQLException;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootShardingjdbcMybatisApplicationTests {

    @Autowired
    private OrderMapper orderMapper;

    @Test
    public void testSharding() throws SQLException, IOException {

        // 0库0表
        OrderDomain orderDomain_0_0 = new OrderDomain(2l,2l);
        orderMapper.save(orderDomain_0_0);

        // 1库1表
        OrderDomain orderDomain_0_1 = new OrderDomain(2l,1l);
        orderMapper.save(orderDomain_0_1);

        // 1库0表
        OrderDomain orderDomain_1_0 = new OrderDomain(1l,2l);
        orderMapper.save(orderDomain_1_0);

        // 1库1表
        OrderDomain orderDomain_1_1 = new OrderDomain(1l,1l);
        orderMapper.save(orderDomain_1_1);
    }
}

如果你还搞定不定你就直接下载这个项目的Demo

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 我可以为你提供一些关于使用SpringBoot ShardingJDBC MyBatis进行分库分表的建议,例如:1. 使用ShardingSphere框架定义数据库分片策略;2. 使用MyBatis实现MyBatis SQL脚本;3. 使用SpringBoot注解的方式定义数据源和ShardingJDBC的配置。 ### 回答2: 使用SpringBoot ShardingJDBCMyBatis可以很方便地实现分库分表功能。首先,ShardingJDBC是一个轻量级的数据库中间件,可以将数据分散到不同的数据库实例中,从而实现分库的效果。其次,MyBatis是一个流行的持久层框架,可以通过XML或注解的方式与数据库进行交互。 在使用SpringBoot ShardingJDBCMyBatis分库分表时,首先需要配置ShardingJDBC的数据源和分片规则。可以通过编写一个配置类来配置分库分表的规则,例如可以根据某个字段的取值来确定数据应该分散到哪个库或表中。配置完成后,就可以在MyBatis的Mapper接口中直接使用分库分表的数据源,从而实现对不同数据库或表的访问。 在编写Mapper接口时,可以使用MyBatis提供的注解或XML方式来编写SQL语句。在SQL语句中,可以使用ShardingJDBC提供的分片键来实现对特定库或表的访问。例如,在需要查询特定表的数据时,可以使用ShardingJDBC提供的Hint注解将查询操作路由到相应的表上。 总的来说,使用SpringBoot ShardingJDBCMyBatis可以实现简单、高效的分库分表功能。通过配置ShardingJDBC的分片规则和使用MyBatis编写SQL语句,可以将数据分散到不同的数据库实例和表中,从而实现了水平扩展和负载均衡的效果。这种方式能够帮助我们提高数据库的性能和容量,从而更好地应对大规模的数据存储需求。 ### 回答3: 使用SpringBoot ShardingJDBC MyBatis可以轻松实现分库分表。 首先,ShardingJDBC是一个分库分表的开源框架,它可以通过数据库中间件实现数据的分散存储。而SpringBoot是一个快速构建项目的框架,可以帮助开发者轻松集成各种组件。 使用SpringBoot ShardingJDBC MyBatis进行分库分表,首先需要配置ShardingJDBC的数据源、分片策略以及分表策略。可以通过配置文件或者编程方式来完成配置。配置数据源时,可以指定多个数据库的连接信息,并使用分片策略将数据分配到不同的数据库中。配置分表策略时,可以指定不同的分表规则,将数据根据一定的规则分散存储在不同的表中。 在具体的业务逻辑中,可以使用MyBatis来操作数据库。MyBatis是一个简化数据库访问的持久层框架,通过编写SQL语句和映射文件,可以轻松实现数据库的增删改查操作。 在访问数据库时,ShardingJDBC会根据配置的分片策略和分表策略,自动将数据路由到指定的数据库和表中。开发者不需要关心数据的具体存储位置,只需要使用MyBatis的API进行数据操作即可。 使用SpringBoot ShardingJDBC MyBatis进行分库分表,可以提高数据库的读写性能,增加数据的存储容量,并且可以实现数据的动态扩容和迁移。此外,由于SpringBootMyBatis的高度集成,开发者可以更加方便地进行开发和维护。 总之,使用SpringBoot ShardingJDBC MyBatis进行分库分表可以帮助开发者更好地管理数据,提升系统的性能和可扩展性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值