前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >shardingJdbc专题系列(三)之Inline策略分库

shardingJdbc专题系列(三)之Inline策略分库

作者头像
一缕82年的清风
发布2021-12-06 10:10:20
5600
发布2021-12-06 10:10:20
举报
文章被收录于专栏:lsqingfeng

上一篇文章我们主要搭建了一个分库分表的脚手架。里边集成了springboot框架,和mybats-plus以及相应表的增删改查。那么接下来我们就简单体验一下分库分表的实现。

一。 需求分析

我们采用最简单的 inline行内表达式策略,通过yml文件中几行简单的配置,来实现一个简单的分库操作。分库的策略是这样的,我们向订单表中插入10条数据,订单表中有订单id和用户id, 订单id我们采用雪花id的生成算法,用户id采用自增的方式,我们又两个库,ds0和ds1, 然后 userId%2, 匹配到不同库中,比如userId是1就保存到ds1库中,userId是2就保存到ds0库中,关于数据库结构,请参看上篇文章,已经给出了sql语句。两个库中都有一个order表。我们通过插入数据,观察效果。

二。 搭建步骤

首先我们创建一个项目module, sharding-inline-yml, (如果已经下载我上篇文章中的脚手架,这个模块已经建好了),依赖sharding-biz模块(该模块是mybatis-plus生成的增删改查), 接下来一步一步来。

一。 添加配置文件

首先添加一个application.yml

代码语言:javascript
复制
server:
  port: 9991

spring:
  profiles:
    active: db

在添加一个配置文件 application-db.yml, (主要是为了后边再加一个application-table.yml演示分表)

代码语言:javascript
复制
# 分库
spring:
  shardingsphere:
    datasource:   #数据源配置
      names: ds0,ds1
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/ds0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: root
      ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/ds1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: root
    sharding:   #分片逻辑
      default-database-strategy:
        inline:
          sharding-column: user_id
          algorithm-expression: ds$->{user_id % 2}
      binding-tables: t_order,t_order_item
      broadcast-tables: t_user
      tables:  #表逻辑
        t_order:
          actual-data-nodes: ds$->{0..1}.t_order
          key-generator:
            column: order_id
            type: SNOWFLAKE
            props:
              worker:
                id: 10
        t_order_item:
          actual-data-nodes: ds$->{0..1}.t_order_item
          key-generator:
            column: order_item_id
            type: SNOWFLAKE
            props:
              worker:
                id: 12

添加Mybatis-plus配置类和启动主类,

接下来就可以测试了:

代码语言:javascript
复制
package cn.cestc.inline.controller;

import cn.cestc.biz.entity.Order;
import cn.cestc.biz.entity.User;
import cn.cestc.biz.service.AddressService;
import cn.cestc.biz.service.OrderItemService;
import cn.cestc.biz.service.OrderService;
import cn.cestc.biz.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.List;

/**
 * @className: TestController
 * @description:
 * @author: sh.Liu
 * @date: 2020-11-15 11:54
 */
@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {

    private final UserService userService;
    private final OrderService orderService;
    private final OrderItemService orderItemService;
    private final AddressService addressService;

    public TestController(UserService userService, OrderService orderService, OrderItemService orderItemService, AddressService addressService) {
        this.userService = userService;
        this.orderService = orderService;
        this.orderItemService = orderItemService;
        this.addressService = addressService;
    }


    @RequestMapping("/user")
    public String testUser(){
        for (int i=1;i<=10; i++) {
            User user = new User();
            user.setUserId(Long.valueOf(i));
            user.setUserName("张三" + i);
            userService.save(user);
        }
        return "sucess";
    }

    @RequestMapping("/order")
    public String testOrder(){
        for (int i=1;i<=10; i++) {
            Order order = new Order();
            order.setUserId(Long.valueOf(i));
            order.setOrderCode("acb"+ i);
            order.setAddressId(String.valueOf(i));
            orderService.save(order);
        }
        return "sucess";
    }

    @RequestMapping("/listOrder")
    public Object testListOrder(){
        List<Order> list = orderService.list(new LambdaQueryWrapper<Order>().in(Order::getUserId, Arrays.asList(1,2,3,4,5)).orderByAsc(Order::getUserId));
        return list;
    }


}

浏览器调用 localhost:9991/test/order, 查看Order表,发现

就这样数据就根据userId的值分散到了不同的库中。

三。 配置分析

那么这个规则是如何生效的呢,其实先秒尽在配置文件当中:

最关键的就是图上的三个红框。

首先配置两个数据源,ds0,ds1,

然后配置的是分库策略: 分片列是 user_id, 就是根据这列数据做分片, 算法表达式:

代码语言:javascript
复制
ds$->{user_id % 2} ,这个应该比较好理解,根据user_id 对2取余结果,计算存入到那个库中,

t_order表的真实表,

代码语言:javascript
复制
ds$->{0..1}.t_order。

存储没问题了之后,也可以测试一下查询,通过查询列表看得到的结果。 要注意,只支持 = 和 in

好了,本篇文章就分享到这里。下一篇我们介绍分表。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/12/01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一。 需求分析
  • 二。 搭建步骤
  • 三。 配置分析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档