Spring Boot集成Sharding JDBC分库分表

背景

近期公司购物车项目需要使用Sharding JDBC分表,特记录下。ps:未分库

依赖引入

<!-- sharding-sphere Version:4.1.1-->
<dependency>
  <groupId>org.apache.shardingsphere</groupId>
  <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
  <version>${sharding-sphere.version}</version>
</dependency>
<dependency>
  <groupId>org.apache.shardingsphere</groupId>
  <artifactId>sharding-jdbc-spring-namespace</artifactId>
  <version>${sharding-sphere.version}</version>
</dependency>

数据库创建

使用函数批量创建,可参考如下函数,测试情况下可创建数量while @j < 表数量 do修改为4张表即可

CREATE DEFINER=`root`@`%` PROCEDURE `batch_create`()
begin
set @str = " (
    `id`            bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '购物车项主键',
    `user_id`       bigint(20) unsigned NOT NULL COMMENT '用户ID',
    `business_type` tinyint(4)          NOT NULL DEFAULT '1' COMMENT '业务线类型 1自取、2包邮、3外卖、4海鲜专送',
    `site_id`       bigint(20)                   DEFAULT '0' COMMENT '地点ID(营业部或门店ID)',
    `group_id`      bigint(20)                   DEFAULT '0' COMMENT '运营组id',
    `item_sku_id`   bigint(20) unsigned NOT NULL COMMENT '商家商品SkuId',
    `merchant_id`   bigint(20)                   DEFAULT '0' COMMENT '商家编码',
    `quantity`      int(10) unsigned    NOT NULL COMMENT '商品数量',
    `create_time`   datetime            NOT NULL COMMENT '创建时间',
    `update_time`   datetime            NOT NULL COMMENT '修改时间',
    `is_selected`   tinyint(4)          NOT NULL DEFAULT '2' COMMENT '是否选中 1未选中 2选中',
    `extra`         varchar(1024)                DEFAULT NULL COMMENT '扩展字段',
    PRIMARY KEY (`id`),
    UNIQUE KEY `uni_cart` (`user_id`, `business_type`, `site_id`, `item_sku_id`),
    KEY `idx_user_id` (`user_id`),
    KEY `idx_id_and_quantity` (`id`, `quantity`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1000000
  DEFAULT CHARSET = utf8mb4 COMMENT ='购物车' ";
set @j = 0;
while @j < 4 do
set @table = concat('cart_',@j);
set @sql_t = concat("CREATE TABLE ",@table,@str);
prepare sql_t from @sql_t;
execute sql_t;
set @j = @j + 1;
end while;
end

YAML配置

logging:
  level:
    com.atmoon.sharding.mapper: info
spring:
  profiles:
    active: dev
  shardingsphere:
    props:
      sql.show: true # 线上环境需要关闭
    datasource:
      names: ds0
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://xxx.xxx.xxx.xxx:3306/sharding-jdbc?serverTimezone=Asia/Shanghai&autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
        username: root
        password: ******
        maxActive: 100
        maxWait: 1000
    sharding:
      default-data-source-name: ds0
      tables:
        cart:
          keyGenerator:
            type: SNOWFLAKE
            column: id
          actual-data-nodes: ds0.cart_$->{0..3} #表后缀从0开始这里为0..n-1, 后缀从1开始这里为1..n, n为多少张表,
          database-strategy:
            inline:
              sharding-column: id
              algorithm-expression: ds0
          table-strategy:
            inline:
              sharding-column: id
              algorithm-expression: cart_$->{id.intdiv(1000) % 4} #建议多少张表余多少
  application:
    name: cart-demo
  jackson:
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss
mybatis-plus:
  mapper-locations: classpath:/mapping/*.xml
  configuration:
    # 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN(下划线命名) 到经典 Java 属性名 aColumn(驼峰命名) 的类似映射
    map-underscore-to-camel-case: true
    cache-enabled: false
    # 开启mybatis-plus全sql 打印,仅可开发测试环境开启
    # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.jarvan.sharding.entity
  global-config:
    db-config:
      # 主键类型  AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
      id-type: AUTO
      update-strategy: not_null
      #驼峰下划线转换
      column-underline: true
      logic-delete-value: 1
      logic-not-delete-value: 0

插入测试

public class CartMapperTest extends BaseTest {


    @Autowired
    CartMapper cartMapper;

    @Test
    public void addTest() {
        for (long i = 1; i < 15; i++) {
            CartDO cart = new CartDO(null, i, 1, 1L, 1L,
                    i, 1001L, 1, new Date(), new Date(), 1, null);
            cartMapper.insert(cart);
        }
    }

    @Test
    public void findTest() {
        List<CartDO> byUserId = cartMapper.findByUserId(1);
        Assert.assertTrue(byUserId.size() > 0);
    }
}

测试结果

upload successful

分库配置

分库配置参考如下

dataSources:
  ds0: !!org.apache.commons.dbcp.BasicDataSource
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ds0
    username: root
    password: 
  ds1: !!org.apache.commons.dbcp.BasicDataSource
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ds1
    username: root
    password: 

shardingRule:  
  tables:
    t_order: 
      actualDataNodes: ds${0..1}.t_order${0..1}
      databaseStrategy:
        inline:
          shardingColumn: user_id
          algorithmExpression: ds${user_id % 2}
      tableStrategy: 
        inline:
          shardingColumn: order_id
          algorithmExpression: t_order${order_id % 2}
      keyGenerator:
        type: SNOWFLAKE
        column: order_id
    t_order_item:
      actualDataNodes: ds${0..1}.t_order_item${0..1}
      databaseStrategy:
        inline:
          shardingColumn: user_id
          algorithmExpression: ds${user_id % 2}
      tableStrategy:
        inline:
          shardingColumn: order_id
          algorithmExpression: t_order_item${order_id % 2}  
  bindingTables:
    - t_order,t_order_item
  broadcastTables:
    - t_config

  defaultDataSourceName: ds0
  defaultTableStrategy:
    none:
  defaultKeyGenerator:
    type: SNOWFLAKE
    column: order_id

props:
  sql.show: true

项目地址

https://github.com/JarvanBest/sharding-demo.git/

猜你喜欢

转载自blog.csdn.net/Jarvanxy/article/details/132339292