分庫分表之_分庫分表 + 複雜查詢

前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

代碼配置暫時和和分庫分表之_分庫分表相同。但是爲了測試下面的join查詢將user表的數量調整到了和company表的數量一致,以及給company添加了一個新的字段ref_user_id

1、開始Demo

1.1、hlj-08-sharding_db_table-range_group.sql


drop database if exists ds_0;
create database ds_0 character set 'utf8' collate 'utf8_general_ci';
use ds_0;

drop table if exists user_0;
create table `user_0`
(
  id          bigint(20) unsigned not null,
  city        varchar(20)         not null default '',
  name        varchar(20)         not null default '',
  age         int(11)             not null default 0,
  status      int(10)             not null default '0' comment '狀態',
  create_time datetime            not null default current_timestamp comment '創建時間',
  update_time datetime            not null default current_timestamp on update current_timestamp comment '修改時間',
  primary key (id)
) engine = innodb
  default charset = utf8;

drop table if exists user_1;
create table `user_1`
(
  id          bigint(20) unsigned not null,
  city        varchar(20)         not null default '',
  name        varchar(20)         not null default '',
  age         int(11)             not null default 0,
  status      int(10)             not null default '0' comment '狀態',
  create_time datetime            not null default current_timestamp comment '創建時間',
  update_time datetime            not null default current_timestamp on update current_timestamp comment '修改時間',
  primary key (id)
) engine = innodb
  default charset = utf8;




drop table if exists company_0;
create table `company_0`
(
  id                   bigint(20) unsigned not null comment '主鍵',
  ref_user_id          bigint(20) unsigned not null comment '主鍵',
  name                 varchar(20)         not null default '' comment '企業名稱',
  company_name_english varchar(128)        not null default '' comment '企業英文名稱',
  status               int(10)             not null default '0' comment '狀態',
  create_time          datetime            not null default current_timestamp comment '創建時間',
  update_time          datetime            not null default current_timestamp on update current_timestamp comment '修改時間',

  primary key (id)
) engine = innodb
  default charset = utf8;

drop table if exists company_1;
create table `company_1`
(
  id                   bigint(20) unsigned not null comment '主鍵',
  ref_user_id          bigint(20) unsigned not null comment '主鍵',
  name                 varchar(20)         not null default '' comment '企業名稱',
  company_name_english varchar(128)        not null default '' comment '企業英文名稱',
  status               int(10)             not null default '0' comment '狀態',
  create_time          datetime            not null default current_timestamp comment '創建時間',
  update_time          datetime            not null default current_timestamp on update current_timestamp comment '修改時間',

  primary key (id)
) engine = innodb
  default charset = utf8;



CREATE TABLE `demo_entity`
(
  id            bigint(20) unsigned NOT NULL COMMENT '主鍵',
  `name`        varchar(64)         NOT NULL,
  `phone`       varchar(20)                  DEFAULT '' COMMENT '手機號',
  `email`       varchar(64)                  DEFAULT '' COMMENT '郵箱',
  `age`         int(10)                      DEFAULT NULL,
  `status`      varchar(8)          NOT NULL COMMENT '狀態',
  `create_user` bigint(16) unsigned          DEFAULT NULL COMMENT '創建人',
  `create_name` varchar(64)                  DEFAULT '' COMMENT '創建人名稱',
  `create_time` datetime            NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',
  `update_user` bigint(16) unsigned          DEFAULT NULL COMMENT '更新人',
  `update_name` varchar(64)                  DEFAULT '' COMMENT '更新人名稱',
  `update_time` datetime            NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  PRIMARY KEY (id)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;



drop database if exists ds_1;
create database ds_1 character set 'utf8' collate 'utf8_general_ci';
use ds_1;

drop table if exists user_0;
create table `user_0`
(
  id          bigint(20) unsigned not null,
  city        varchar(20)         not null default '',
  name        varchar(20)         not null default '',
  age         int(11)             not null default 0,
  status      int(10)             not null default '0' comment '狀態',
  create_time datetime            not null default current_timestamp comment '創建時間',
  update_time datetime            not null default current_timestamp on update current_timestamp comment '修改時間',
  primary key (id)
) engine = innodb
  default charset = utf8;

drop table if exists user_1;
create table `user_1`
(
  id          bigint(20) unsigned not null,
  city        varchar(20)         not null default '',
  name        varchar(20)         not null default '',
  age         int(11)             not null default 0,
  status      int(10)             not null default '0' comment '狀態',
  create_time datetime            not null default current_timestamp comment '創建時間',
  update_time datetime            not null default current_timestamp on update current_timestamp comment '修改時間',
  primary key (id)
) engine = innodb
  default charset = utf8;



drop table if exists company_0;
create table `company_0`
(
  id                   bigint(20) unsigned not null comment '主鍵',
  ref_user_id          bigint(20) unsigned not null comment '主鍵',
  name                 varchar(20)         not null default '' comment '企業名稱',
  company_name_english varchar(128)        not null default '' comment '企業英文名稱',
  status               int(10)             not null default '0' comment '狀態',
  create_time          datetime            not null default current_timestamp comment '創建時間',
  update_time          datetime            not null default current_timestamp on update current_timestamp comment '修改時間',

  primary key (id)
) engine = innodb
  default charset = utf8;

drop table if exists company_1;
create table `company_1`
(
  id                   bigint(20) unsigned not null comment '主鍵',
  ref_user_id          bigint(20) unsigned not null comment '主鍵',
  name                 varchar(20)         not null default '' comment '企業名稱',
  company_name_english varchar(128)        not null default '' comment '企業英文名稱',
  status               int(10)             not null default '0' comment '狀態',
  create_time          datetime            not null default current_timestamp comment '創建時間',
  update_time          datetime            not null default current_timestamp on update current_timestamp comment '修改時間',

  primary key (id)
) engine = innodb
  default charset = utf8;



1.1.1、數據庫圖文

1585561704857

1.2、依賴


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

1.3、配置文件:application.properties

server.port=8888


# 配置 mybatis的一些配置,也可以在 application.properties 中配置,如果配置了就不需要了mybatis.xml
#mybatis-plus.config-location=classpath:mybatis.xml
#Maven 多模塊項目的掃描路徑需以 classpath*: 開頭 (即加載多個 jar 包下的 XML 文件)
mybatis-plus.mapper-locations=classpath*:mapper/*.xml
mybatis-plus.type-aliases-package=com.healerjean.proj.pojo
##主鍵類型  0:"數據庫ID自增,非常大", 1:"用戶輸入ID(如果用戶不輸入,則默認是0)",2:"全局唯一ID (數字類型唯一ID)", 3:"全局唯一ID UUID";
mybatis-plus.id-type: 0
#字段策略 0:"忽略判斷",1:"非 NULL 判斷"),2:"非空判斷"
mybatis-plus.field-strategy: 2
#數據庫大寫下劃線轉換
mybatis-plus.capital-mode: true
mybatis-plus.refresh-mapper: true


# #當遇到同樣名字的時候,是否允許覆蓋註冊
spring.main.allow-bean-definition-overriding=true
# 顯示SQL
spring.shardingsphere.props.sql.show=true



##############################
## 分庫分表
#############################
spring.shardingsphere.datasource.names=ds0,ds1

# 數據源
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://localhost:3306/ds_0?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456

spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://localhost:3306/ds_1?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456


# 分庫配置
#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=id
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds$->{id % 2}
spring.shardingsphere.sharding.default-database-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.default-database-strategy.standard.precise-algorithm-class-name=com.healerjean.proj.config.datasource.CustomShardingDBAlgorithm


# user  company 分表
# user_0,user_1,user_2(自定義分表算法)
spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds$->{0..1}.user_$->{0..1}
spring.shardingsphere.sharding.tables.user.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name=com.healerjean.proj.config.datasource.CustomShardingTableAlgorithm
# company_0,company_1 (inline分表策略 表達式 id%2)
spring.shardingsphere.sharding.tables.company.actual-data-nodes=ds$->{0..1}.company_$->{0..1}
spring.shardingsphere.sharding.tables.company.database-strategy.inline.sharding-column=ref_user_id
spring.shardingsphere.sharding.tables.company.database-strategy.inline.algorithm-expression=ds${ref_user_id.longValue() % 2}
spring.shardingsphere.sharding.tables.company.table-strategy.inline.sharding-column=ref_user_id
spring.shardingsphere.sharding.tables.company.table-strategy.inline.algorithm-expression=company_${ref_user_id.longValue() % 2}


## 默認數據源指定(不分庫的表)
spring.shardingsphere.sharding.default-data-source-name=ds0

1.4、具體測試方法和類

1.4.1、實體類

1.4.1.1、User.java

@Data
@Accessors(chain = true)
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    /** 主鍵  */
    private Long id;
    private String name;
    private String city;
    private Integer age;
    private String status;
    private Date createTime;
    private Date updateTime;
}

1.4.1.2、Company.java

@Data
public class Company {

	private Long id;
	private Long refUserId;
	private String name;
	private String companyNameEnglish;
	private String status;
	private Date createTime;
	private Date updateTime;
}


1.4.1.3、DemoEntity.java

@Data
@Accessors(chain = true)
public class DemoEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    private Long id;
    private String name;
    private String phone;
    private String email;
    private Integer age;
    private String status;
    private Long createUser;
    private String createName;
    private java.util.Date createTime;
    private Long updateUser;
    private String updateName;
    private java.util.Date updateTime;

}

1.4.1.4、新對象 UserRefCompany

@Data
public class UserRefCompany {

    /** 主鍵  */
    private Long userId;
    private String name;
    private String city;
    private String status;

    private Long companyId;
    private String companyName;
    private String companyNameEnglish;


    private Integer avgAge;
    private Integer sumAge;


}

1.4.2、DTO數據

1.4.2.1、UserDTO.java

@Data
@Accessors(chain = true)
@ApiModel(value = "demo實體類")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserDTO {


    @ApiModelProperty(value = "主鍵", hidden = true)
    @JsonSerialize(using = JsonLongSerializer.class )
    private Long id;

    @ApiModelProperty(value = "姓名")
    @NotBlank(message = "姓名不能爲空", groups = ValidateGroup.HealerJean.class)
    private String name;

    @ApiModelProperty(value = "城市")
    private String city;

    @ApiModelProperty(value = "年齡")
    private Integer age;


    @ApiModelProperty(value = "狀態", hidden = true)
    private String status;


    @ApiModelProperty(value = "創建時間", hidden = true)
    @JsonFormat(pattern = DateUtils.YYYY_MM_dd_HH_mm_ss, timezone = "GMT+8")
    private Date createTime;

    @ApiModelProperty(value = "修改時間", hidden = true)
    @JsonFormat(pattern = DateUtils.YYYY_MM_dd_HH_mm_ss, timezone = "GMT+8")
    private Date updateTime;

    private Integer pageNow ;
    private Integer pageSize ;

}

1.4.2.2、CompanyDTO.java

@Data
public class CompanyDTO {

    @JsonSerialize(using = JsonLongSerializer.class)
    private Long id;

    private Long refUserId;

    private String name;
    private String companyNameEnglish;
    private String status;


    @ApiModelProperty(value = "創建時間", hidden = true)
    @JsonFormat(pattern = DateUtils.YYYY_MM_dd_HH_mm_ss, timezone = "GMT+8")
    private Date createTime;

    @ApiModelProperty(value = "修改時間", hidden = true)
    @JsonFormat(pattern = DateUtils.YYYY_MM_dd_HH_mm_ss, timezone = "GMT+8")
    private Date updateTime;
}


1.4.2.3、DemoDTO.java

@Data
@Accessors(chain = true)
@ApiModel(value = "demo實體類")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DemoDTO extends PageQuery {

    @JsonSerialize(using = JsonLongSerializer.class )
    private Long id;

    @ApiModelProperty(value = "姓名")
    @NotBlank(message = "姓名不能爲空", groups = ValidateGroup.HealerJean.class)
    private String name;

    @ApiModelProperty(value = "年齡")
    private Integer age;

    @ApiModelProperty(value = "手機號")
    private String phone;

    @ApiModelProperty(value = "郵箱")
    private String email;

    @ApiModelProperty(value = "是否刪除,10可用,99刪除 ", hidden = true)
    private String status;

    @ApiModelProperty(value = "創建人", hidden = true)
    private Long createUser;

    @ApiModelProperty(value = "創建人名字", hidden = true)
    private String createName;

    @ApiModelProperty(value = "創建時間", hidden = true)
    private java.util.Date createTime;

    @ApiModelProperty(value = "更新人", hidden = true)
    private Long updateUser;

    @ApiModelProperty(value = "更新人名稱", hidden = true)
    private String updateName;

    @ApiModelProperty(hidden = true)
   private java.util.Date updateTime;

}

1.4.3、Mapper

1.4.3.1、UserMapper.java

public interface UserMapper extends BaseMapper<User> {


}

1.4.3.1、CompanyMapper.java

public interface CompanyMapper  extends BaseMapper<Company> {


}

1.4.3.1、DemoEntityMapper.java

public interface DemoEntityMapper extends BaseMapper<DemoEntity> {

}

1.4.4、Service

1.4.4.1、 UserService.java

public interface UserService {


    UserDTO insert(UserDTO userDTO);

    UserDTO findById(Long id);

    List<UserDTO> list();

}

1.4.4.2、 CompanyService.java

public interface CompanyService {


    CompanyDTO insert(CompanyDTO companyDTO);

    CompanyDTO findById(Long id);

    List<CompanyDTO> list();
}

1.4.4.3、 DemoEntityService.java

public interface DemoEntityService {


    DemoDTO insert(DemoDTO demoEntity);

    DemoDTO findById(Long id);

    List<DemoDTO> list();

}

1.4.5、ServiceImpl.java

1.4.5.1、UserServiceImpl.java

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;


    @Override
    public UserDTO insert(UserDTO userDTO) {
        User user = BeanUtils.dtoToUserDTO(userDTO);
        user.setStatus(StatusEnum.生效.code);
        userMapper.insert(user);
        userDTO.setId(user.getId());
        return userDTO;
    }

    @Override
    public UserDTO findById(Long id) {
        User user = userMapper.selectById(id);
        return user == null ? null : BeanUtils.userToDTO(user);
    }

    @Override
    public List<UserDTO> list() {
        List<User> users = userMapper.selectList(null);
        List<UserDTO> list = null;
        if (!EmptyUtil.isEmpty(users)) {
            list = users.stream().map(BeanUtils::userToDTO).collect(Collectors.toList());
        }
        return list;
    }

}

1.4.5.2、CompanyServiceImpl.java

@Service
public class CompanyServiceImpl implements CompanyService {

    @Resource
    private CompanyMapper companyMapper;

    @Override
    public CompanyDTO insert(CompanyDTO companyDTO) {
        Company company = BeanUtils.dtoToCompany(companyDTO);
        company.setStatus(StatusEnum.生效.code);
        companyMapper.insert(company);
        companyDTO.setId(company.getId());
        return companyDTO;
    }

    @Override
    public CompanyDTO findById(Long id) {
        Company company = companyMapper.selectById(id);
        return company == null ? null : BeanUtils.companyToDTO(company);
    }

    @Override
    public List<CompanyDTO> list() {
        List<Company> companys = companyMapper.selectList(null);
        List<CompanyDTO> list = null;
        if (!EmptyUtil.isEmpty(companys)) {
            list = companys.stream().map(BeanUtils::companyToDTO).collect(Collectors.toList());
        }
        return list;
    }
}

1.4.5.3、DemoEntityServiceImpl.java

@Service
@Slf4j
public class DemoEntityServiceImpl implements DemoEntityService {


    @Resource
    private DemoEntityMapper demoEntityMapper;

    @Resource
    private CompanyService companyService;
    @Resource
    private UserService userService;

    @Override
    public DemoDTO insert(DemoDTO demoDTO) {
        DemoEntity demoEntity = BeanUtils.dtoToDemo(demoDTO);
        demoEntity.setStatus(StatusEnum.生效.code);
        demoEntityMapper.insert(demoEntity);
        demoDTO.setId(demoEntity.getId());
        return demoDTO;
    }


    @Override
    public DemoDTO findById(Long id) {
        DemoEntity demoEntity = demoEntityMapper.selectById(id);
        return demoEntity == null ? null : BeanUtils.demoToDTO(demoEntity);
    }

    @Override
    public List<DemoDTO> list() {
        List<DemoDTO> collect = null;
        List<DemoEntity> list = demoEntityMapper.selectList(null);
        if (!EmptyUtil.isEmpty(list)) {
            collect = list.stream().map(BeanUtils::demoToDTO).collect(Collectors.toList());
        }
        return collect;
    }


}

1.4.6、Controller

1.4.6.1、UserController.java

@ApiResponses(value = {
        @ApiResponse(code = 200, message = "訪問正常"),
        @ApiResponse(code = 301, message = "邏輯錯誤"),
        @ApiResponse(code = 500, message = "系統錯誤"),
        @ApiResponse(code = 401, message = "未認證"),
        @ApiResponse(code = 403, message = "禁止訪問"),
        @ApiResponse(code = 404, message = "url錯誤")
})
@Api(description = "demo控制器")
@Controller
@RequestMapping("hlj/demo")
@Slf4j
public class UserController {



    @Autowired
    private UserService userService;

    @ApiOperation(value = "insert",
            notes = "insert",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @PostMapping(value = "insert", produces = "application/json; charset=utf-8")
    @ResponseBody
    public ResponseBean insert(UserDTO userDTO) {
        log.info("樣例--------mybaits-plus添加demo實體------數據信息{}", userDTO);
        String validate = ValidateUtils.validate(userDTO, ValidateGroup.HealerJean.class);
        if (!validate.equals(CommonConstants.COMMON_SUCCESS)) {
            throw new BusinessException(ResponseEnum.參數錯誤, validate);
        }
        return ResponseBean.buildSuccess(userService.insert(userDTO));
    }


    @ApiOperation(notes = "findById",
            value = "findById",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "demo主鍵", required = true, paramType = "path", dataType = "long"),
    })
    @GetMapping("findById/{id}")
    @ResponseBody
    public ResponseBean findById(@PathVariable Long id) {
        log.info("樣例--------findById------數據:id:{}", id);
        return ResponseBean.buildSuccess(userService.findById(id));
    }

    @ApiOperation(notes = "list",
            value = "list",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @GetMapping("list")
    @ResponseBody
    public ResponseBean list() {
        log.info("樣例--------list------");
        return ResponseBean.buildSuccess(userService.list());
    }


}

1.4.6.2、CompanyController.java

@ApiResponses(value = {
        @ApiResponse(code = 200, message = "訪問正常"),
        @ApiResponse(code = 301, message = "邏輯錯誤"),
        @ApiResponse(code = 500, message = "系統錯誤"),
        @ApiResponse(code = 401, message = "未認證"),
        @ApiResponse(code = 403, message = "禁止訪問"),
        @ApiResponse(code = 404, message = "url錯誤")
})
@Api(description = "demo控制器")
@Controller
@RequestMapping("hlj/company")
@Slf4j
public class CompanyController {


    @Autowired
    private CompanyService companyService;

    @ApiOperation(value = "insert",
            notes = "insert",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @PostMapping(value = "insert", produces = "application/json; charset=utf-8")
    @ResponseBody
    public ResponseBean insert(CompanyDTO companyDTO) {
        log.info("user--------insert------請求參數:{}", companyDTO);
        return ResponseBean.buildSuccess(companyService.insert(companyDTO));
    }


    @ApiOperation(notes = "findById",
            value = "findById",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "demo主鍵", required = true, paramType = "path", dataType = "long"),
    })
    @GetMapping("findById/{id}")
    @ResponseBody
    public ResponseBean findById(@PathVariable Long id) {
        log.info("company--------findById------id:{}", id);
        return ResponseBean.buildSuccess(companyService.findById(id));
    }



    @ApiOperation(notes = "list",
            value = "list",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @GetMapping("list")
    @ResponseBody
    public ResponseBean list() {
        log.info("company--------list------");
        return ResponseBean.buildSuccess(companyService.list());
    }

}

1.4.6.3、DemoController.java

@ApiResponses(value = {
        @ApiResponse(code = 200, message = "訪問正常"),
        @ApiResponse(code = 301, message = "邏輯錯誤"),
        @ApiResponse(code = 500, message = "系統錯誤"),
        @ApiResponse(code = 401, message = "未認證"),
        @ApiResponse(code = 403, message = "禁止訪問"),
        @ApiResponse(code = 404, message = "url錯誤")
})
@Api(description = "demo控制器")
@Controller
@RequestMapping("hlj/demo")
@Slf4j
public class DemoController {

    @Autowired
    private DemoEntityService demoEntityService;


    @ApiOperation(value = "insert",
            notes = "insert",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @PostMapping(value = "insert", produces = "application/json; charset=utf-8")
    @ResponseBody
    public ResponseBean insert(DemoDTO demoDTO) {
        log.info("demo--------insert------請求參數:{}", demoDTO);
        return ResponseBean.buildSuccess(demoEntityService.insert(demoDTO));
    }


    @ApiOperation(notes = "findById",
            value = "findById",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "demo主鍵", required = true, paramType = "path", dataType = "long"),
    })
    @GetMapping("findById/{id}")
    @ResponseBody
    public ResponseBean findById(@PathVariable Long id) {
        log.info("demo--------findById------id:{}", id);
        return ResponseBean.buildSuccess(demoEntityService.findById(id));
    }



    @ApiOperation(notes = "list",
            value = "list",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @GetMapping("list")
    @ResponseBody
    public ResponseBean list() {
        log.info("demo--------list------");
        return ResponseBean.buildSuccess(demoEntityService.list());
    }

}

1.4.6、自定義分表算法 CustomShardingTableAlgorithm

@Slf4j
public class CustomShardingTableAlgorithm implements PreciseShardingAlgorithm<Long> {

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
        for (String tableName : availableTargetNames) {
            if (tableName.endsWith(shardingValue.getValue() % 3 + "")) {
                log.info("表爲:{}, 主鍵爲:{}, 最終被分到的表爲:{}", availableTargetNames, shardingValue, tableName);
                return tableName;
            }
        }
        throw new IllegalArgumentException();
    }
}

1.4.7、自定義分庫算法:CustomShardingDBAlgorithm

@Slf4j
public class CustomShardingDBAlgorithm implements PreciseShardingAlgorithm<Long> {


    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
        for (String dbName : availableTargetNames) {
            if (dbName.endsWith(shardingValue.getValue() % 2 + "")) {
                log.info("庫爲:{}, 主鍵爲:{}, 最終被分到的庫爲:【{}】", availableTargetNames, shardingValue, dbName);
                return dbName;
            }
        }
        throw new IllegalArgumentException();
    }
}

2、開始測試

基本的增刪改成就不測試了,我們這裏主要是測試一些分庫後可能出問題的一些語句

2.1、limit查詢:成功

2.1.1、代碼如下

2.1.1.1、UserService.java

public interface UserService {

    List<UserDTO> limit(UserDTO userDTO);

}

2.1.1.2、UserServiceImpl.java

@Service
@Slf4j
public class UserServiceImpl implements UserService {


    /**
     * limit 成功
     */
    @Override
    public List<UserDTO> limit(UserDTO userDTO) {
        Wrapper<User> userWrapper = new QueryWrapper<User>().lambda()
            .orderByDesc(User::getCreateTime)
            .last("limit " + userDTO.getPageNow() + ", " + userDTO.getPageSize());
        List<User> users = userMapper.selectList(userWrapper);
        List<UserDTO> list = null;
        if (!EmptyUtil.isEmpty(users)) {
            list = users.stream().map(BeanUtils::userToDTO).collect(Collectors.toList());
        }
        return list;
    }


}

2.1.1.3、UserController.java

@Controller
@RequestMapping("hlj/user")
@Slf4j
public class UserController {

    @ApiOperation(notes = "limit",
            value = "limit",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @GetMapping("limit")
    @ResponseBody
    public ResponseBean limit(UserDTO userDTO) {
        log.info("demo--------limit------");
        return ResponseBean.buildSuccess(userService.limit(userDTO));
    }


}

2.1.2、訪問測試

現在所有的User表數據彙總:

name city age createTime
a 北京 1 2020-03-30 18:15:14
b 北京 2 2020-03-30 18:16:14
c 山西 3 2020-03-30 18:16:20
d 山西 4 2020-03-30 18:16:27
e 河北 5 2020-03-30 18:16:38
f 江蘇 6 2020-03-30 18:16:46

2.1.2.1、訪問:pageNow:0,pageSize:2

{
  "success": true,
  "result": [
    {
      "id": "1244569246752800769",
      "name": "f",
      "city": "江蘇",
      "age": 6,
      "status": "10",
      "createTime": "2020-03-30 18:16:46",
      "updateTime": "2020-03-30 18:16:46"
    },
    {
      "id": "1244569214813175810",
      "name": "e",
      "city": "河北",
      "age": 5,
      "status": "10",
      "createTime": "2020-03-30 18:16:38",
      "updateTime": "2020-03-30 18:16:38"
    }
  ],
  "msg": "",
  "code": 200,
  "date": "1585563469572"
}



控制檯sql日誌

# 日誌彙總
Logic SQL: 
SELECT  id,name,city,age,status,create_time,update_time  FROM user 
 ORDER BY create_time DESC limit 0, 2 
 
 
 
# 數據庫日誌 
Actual SQL: ds0 ::: 
SELECT  id,name,city,age,status,create_time,update_time  FROM user_0 
ORDER BY create_time DESC limit 0, 2 ShardingSphere-SQL.log[89]

Actual SQL: ds0 ::: 
SELECT  id,name,city,age,status,create_time,update_time  FROM user_1 
 ORDER BY create_time DESC limit 0, 2
 
Actual SQL: ds1 ::: 
SELECT  id,name,city,age,status,create_time,update_time  FROM user_0 
 ORDER BY create_time DESC limit 0, 2 
 
Actual SQL: ds1 ::: 
SELECT  id,name,city,age,status,create_time,update_time  FROM user_1 
ORDER BY create_time DESC limit 0, 2 

2.1.2.2、訪問:pageNow:3,pageSize:1

{
  "success": true,
  "result": [
    {
      "id": "1244569141396078594",
      "name": "c",
      "city": "山西",
      "age": 3,
      "status": "10",
      "createTime": "2020-03-30 18:16:20",
      "updateTime": "2020-03-30 18:16:20"
    }
  ],
  "msg": "",
  "code": 200,
  "date": "1585563506891"
}

控制檯sql日誌



# 日誌彙總
Actual SQL: 
SELECT  id,name,city,age,status,create_time,update_time  FROM user ORDER BY create_time DESC limit 3, 1 
 
  
# 數據庫日誌 
Actual SQL: ds0 ::: 
SELECT  id,name,city,age,status,create_time,update_time  FROM user_0 ORDER BY create_time DESC limit 0, 4

Actual SQL: ds0 ::: 
SELECT  id,name,city,age,status,create_time,update_time  FROM user_1 ORDER BY create_time DESC limit 0, 4

Actual SQL: ds1 ::: 
SELECT  id,name,city,age,status,create_time,update_time  FROM user_0 ORDER BY create_time DESC limit 0, 4

Actual SQL: ds1 ::: 
SELECT  id,name,city,age,status,create_time,update_time  FROM user_1 ORDER BY create_time DESC limit 0, 4

2.1.3、歸納總結:

成功,可以看到分表向每個數據庫的每個表中發送了sql語句

2.2、groupBy + 函數 :成功

2.2.1、代碼如下

2.2.1.1、UserMapper.java

public interface UserMapper extends BaseMapper<User> {


    List<UserRefCompany> groupByCity();
}

2.2.1.2、UserMapper.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.healerjean.proj.dao.mapper.UserMapper">


    <select id="groupByCity" resultType="com.healerjean.proj.pojo.UserRefCompany">
        select city , sum(age) as sumAge, avg(age) as avgAge  from user  group by city
    </select>


</mapper>

2.2.1.3、UserService.java

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    
    /**
	* groupBy 成功
	*/
    @Override
    public List<UserRefCompany>  group() {
        List<UserRefCompany> list = userMapper.groupByCity();
        return list;
    }

}

2.2.1.4、UserController.java

@Controller
@RequestMapping("hlj/user")
@Slf4j
public class UserController {

    @ApiOperation(notes = "group",
            value = "group",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @GetMapping("group")
    @ResponseBody
    public ResponseBean group() {
        log.info("demo--------group------");
        return ResponseBean.buildSuccess(userService.group());
    }
    
    
}

2.1.2、測試

現在所有的User表數據彙總:

name city age
a 北京 1
b 北京 2
c 山西 3
d 山西 4
e 河北 5
f 江蘇 6

2.1.2.1、訪問測試

{
  "success": true,
  "result": [
    {
      "userId": null,
      "name": null,
      "city": "北京",
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": 1,
      "sumAge": 3
    },
    {
      "userId": null,
      "name": null,
      "city": "山西",
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": 3,
      "sumAge": 7
    },
    {
      "userId": null,
      "name": null,
      "city": "江蘇",
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": 6,
      "sumAge": 6
    },
    {
      "userId": null,
      "name": null,
      "city": "河北",
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": 5,
      "sumAge": 5
    }
  ],
  "msg": "",
  "code": 200,
  "date": "1585563964870"
}

控制檯日誌

Logic SQL: 
select city , sum(age) as sumAge, avg(age) as avgAge  from user  group by city 






Actual SQL: ds0 ::: 
select city , sum(age) as sumAge, avg(age) as avgAge , COUNT(age) AS AVG_DERIVED_COUNT_0 , SUM(age) AS AVG_DERIVED_SUM_0  from user_0  group by city ORDER BY city ASC  ShardingSphere-SQL.log[89]

Actual SQL: ds0 ::: 
select city , sum(age) as sumAge, avg(age) as avgAge , COUNT(age) AS AVG_DERIVED_COUNT_0 , SUM(age) AS AVG_DERIVED_SUM_0  from user_1  group by city ORDER BY city ASC 

Actual SQL: ds1 ::: 
select city , sum(age) as sumAge, avg(age) as avgAge , COUNT(age) AS AVG_DERIVED_COUNT_0 , SUM(age) AS AVG_DERIVED_SUM_0  from user_0  group by city ORDER BY city ASC  

Actual SQL: ds1 ::: 
select city , sum(age) as sumAge, avg(age) as avgAge , COUNT(age) AS AVG_DERIVED_COUNT_0 , SUM(age) AS AVG_DERIVED_SUM_0  from user_1  group by city ORDER BY city ASC  

2.1.3、歸納總結:

成功,可以看到分表向每個數據庫的每個表中發送了sql語句 (取出數據後,自動講裏面獲取的數字進行計算)

2.3、between and :成功

2.3.1、代碼如下

2.3.1.1、UserService.java

public interface UserService {

    List<UserDTO> between();

}

2.3.1.2、UserServiceImpl.java

@Service
@Slf4j
public class UserServiceImpl implements UserService {


    /**
     * between 成功
     */
    @Override
    public List<UserDTO> between() {
        Wrapper<User> userWrapper = new QueryWrapper<User>().lambda()
                .between(User::getAge, 1, 3)
                .orderByDesc(User::getCreateTime);
        List<User> users = userMapper.selectList(userWrapper);
        List<UserDTO> list = null;
        if (!EmptyUtil.isEmpty(users)) {
            list = users.stream().map(BeanUtils::userToDTO).collect(Collectors.toList());
        }
        return list;
    }


}

2.3.1.3、UserController.java

@Controller
@RequestMapping("hlj/user")
@Slf4j
public class UserController {


    @ApiOperation(notes = "between",
            value = "group",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @GetMapping("between")
    @ResponseBody
    public ResponseBean between() {
        log.info("demo--------between------");
        return ResponseBean.buildSuccess(userService.between());
    }



}

2.3.2、測試

現在所有的User表數據彙總:

name city age createTime
a 北京 1 2020-03-30 18:15:14
b 北京 2 2020-03-30 18:16:14
c 山西 3 2020-03-30 18:16:20
d 山西 4 2020-03-30 18:16:27
e 河北 5 2020-03-30 18:16:38
f 江蘇 6 2020-03-30 18:16:46

2.3.2.1、訪問測試 :between 1 and 3 orderby createTime desc

{
  "success": true,
  "result": [
    {
      "id": "1244569141396078594",
      "name": "c",
      "city": "山西",
      "age": 3,
      "status": "10",
      "createTime": "2020-03-30 18:16:20",
      "updateTime": "2020-03-30 18:16:20"
    },
    {
      "id": "1244569114653196290",
      "name": "b",
      "city": "北京",
      "age": 2,
      "status": "10",
      "createTime": "2020-03-30 18:16:14",
      "updateTime": "2020-03-30 18:16:14"
    },
    {
      "id": "1244568862747492353",
      "name": "a",
      "city": "北京",
      "age": 1,
      "status": "10",
      "createTime": "2020-03-30 18:15:14",
      "updateTime": "2020-03-30 18:15:14"
    }
  ],
  "msg": "",
  "code": 200,
  "date": "1585564394319"
}

2.3.3、歸納總結:

成功,可以看到分表向每個數據庫的每個表中發送了sql語句

2.2、left join: 連接查詢

2.2.1、代碼如下

2.2.1.1、UserMapper.java

public interface UserMapper extends BaseMapper<User> {


    List<UserRefCompany> leftJoin();

}


2.2.1.2、UserMapper.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.healerjean.proj.dao.mapper.UserMapper">


    <select id="leftJoin" resultType="com.healerjean.proj.pojo.UserRefCompany">
                 select u.id,
                   u.name ,
                   c.id as companyId,
                   c.name as companyName,
                   c.ref_user_id as refUserId,
                   c.company_name_english as companyNameEnglish
               from user u left join  company c  on u.id = c .ref_user_id 
        		order by  u.create_time
    </select>


</mapper>

2.2.1.3、UserService.java

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    
    /**
     * left join 設置了綁定關係後成功
     */
    @Override
    public List<UserRefCompany> leftJoin() {
        List<UserRefCompany> userRefCompanies = userMapper.leftJoin();
        return userRefCompanies;
    }

}

2.2.1.4、UserController.java

@Controller
@RequestMapping("hlj/user")
@Slf4j
public class UserController {

    @ApiOperation(notes = "leftJoin",
            value = "leftJoin",
            consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE,
            response = UserDTO.class)
    @GetMapping("leftJoin")
    @ResponseBody
    public ResponseBean leftJoin() {
        log.info("demo--------leftJoin------");
        return ResponseBean.buildSuccess( userService.leftJoin());
    }
    
    
}

2.2.2、訪問測試:

現在所有的User表數據彙總:

id name city age
1244568862747492353 a 北京 1
1244569114653196290 b 北京 2
1244569141396078594 c 山西 3
1244569167870525442 d 山西 4
1244569214813175810 e 河北 5
1244569246752800769 f 江蘇 6

現在所有的company表數據彙總、添加這個數據的時候,其實我們已經做了一些小動作了,company表的分庫分表是按照ref_user_id進行分庫的(和user表中id的分庫策略一致),這樣就保證了後面綁定關係之後查詢的成功

id ref_user_id name company_name_english create_time
1244575632182181889 1244568862747492353 北京小米有限公司 xiaomi 2020-03-30 18:42:08
1244575692508856321 1244569114653196290 北京字節跳動 zijie 2020-03-30 18:42:22
1244575754915905538 1244569141396078594 山西愛酷科技 Iku 2020-03-30 18:42:37
1244575817167765506 1244569214813175810 河北騰訊 tecent 2020-03-30 18:42:52

2.2.2.1、默認失敗

{
  "success": true,
  "result": [
    {
      "userId": null,
      "name": "a",
      "city": null,
      "status": null,
      "companyId": 1244585691742093300,
      "companyName": "北京小米有限公司",
      "companyNameEnglish": "xiaomi",
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "a",
      "city": null,
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "b",
      "city": null,
      "status": null,
      "companyId": 1244585869291176000,
      "companyName": "北京字節跳動",
      "companyNameEnglish": "zijie",
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "b",
      "city": null,
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "c",
      "city": null,
      "status": null,
      "companyId": 1244585918465196000,
      "companyName": "山西愛酷科技",
      "companyNameEnglish": "Iku",
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "c",
      "city": null,
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "d",
      "city": null,
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "d",
      "city": null,
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "e",
      "city": null,
      "status": null,
      "companyId": 1244585970768167000,
      "companyName": "河北騰訊",
      "companyNameEnglish": "tecent",
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "e",
      "city": null,
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "f",
      "city": null,
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "f",
      "city": null,
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": null,
      "sumAge": null
    }
  ],
  "msg": "",
  "code": 200,
  "date": "1585567537634"
}
Response Code

控制檯日誌(整理了下),可以看到下面的查詢類似於卡迪爾積,每個x和每個y數組裏面的分別join了一次,所以導致了錯誤的出現,

要查詢的結果
Logic SQL: select u.id,
                   u.name ,
                   c.id as companyId,
                   c.name as companyName,
                   c.ref_user_id as refUserId,
                   c.company_name_english as companyNameEnglish
               from user u
            left join  company c  on u.id = c .ref_user_id ShardingSphere-SQL.log[89]





分庫查詢
Actual SQL: ds0 ::: 
select  ^^^ from user_1 u left join  company_1 c  on u.id = c .ref_user_id               
select  ^^^ from user_1 u left join  company_0 c  on u.id = c .ref_user_id               
select  ^^^ from user_0 u left join  company_1 c  on u.id = c .ref_user_id               
select  ^^^ from user_0 u left join  company_0 c  on u.id = c .ref_user_id             


Actual SQL: ds1 ::: 
select  ^^^ from user_1 u left join  company_1 c  on u.id = c .ref_user_id      
select  ^^^ from user_1 u left join  company_0 c  on u.id = c .ref_user_id      
select  ^^^ from user_0 u left join  company_1 c  on u.id = c .ref_user_id     
select  ^^^ from user_0 u left join  company_0 c  on u.id = c .ref_user_id 
            

2.2.3、配置user和company的綁定關係 :成功

如果要保證一對一的表關係,必須保證2點

1、user和company的表數量以及所在節點要完全一模一樣

2、從表的的外鍵規則和主表的外鍵分庫分表策略要一直

# user  company 分表
# user_0,user_1,user_2(自定義分表算法)
spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds$->{0..1}.user_$->{0..1}
spring.shardingsphere.sharding.tables.user.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name=com.healerjean.proj.config.datasource.CustomShardingTableAlgorithm
# company_0,company_1 (inline分表策略 表達式 id%2)
spring.shardingsphere.sharding.tables.company.actual-data-nodes=ds$->{0..1}.company_$->{0..1}
spring.shardingsphere.sharding.tables.company.database-strategy.inline.sharding-column=ref_user_id
spring.shardingsphere.sharding.tables.company.database-strategy.inline.algorithm-expression=ds${ref_user_id.longValue() % 2}
spring.shardingsphere.sharding.tables.company.table-strategy.inline.sharding-column=ref_user_id
spring.shardingsphere.sharding.tables.company.table-strategy.inline.algorithm-expression=company_${ref_user_id.longValue() % 2}


# 綁定表規則列表
spring.shardingsphere.sharding.binding-tables[0]=user,company

2.2.3.1、訪問測試

{
  "success": true,
  "result": [
    {
      "userId": null,
      "name": "a",
      "city": null,
      "status": null,
      "companyId": 1244585691742093300,
      "companyName": "北京小米有限公司",
      "companyNameEnglish": "xiaomi",
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "b",
      "city": null,
      "status": null,
      "companyId": 1244585869291176000,
      "companyName": "北京字節跳動",
      "companyNameEnglish": "zijie",
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "c",
      "city": null,
      "status": null,
      "companyId": 1244585918465196000,
      "companyName": "山西愛酷科技",
      "companyNameEnglish": "Iku",
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "d",
      "city": null,
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "e",
      "city": null,
      "status": null,
      "companyId": 1244585970768167000,
      "companyName": "河北騰訊",
      "companyNameEnglish": "tecent",
      "avgAge": null,
      "sumAge": null
    },
    {
      "userId": null,
      "name": "f",
      "city": null,
      "status": null,
      "companyId": null,
      "companyName": null,
      "companyNameEnglish": null,
      "avgAge": null,
      "sumAge": null
    }
  ],
  "msg": "",
  "code": 200,
  "date": "1585567592799"
}

控制檯日誌

要查詢的結果
Logic SQL: select u.id,
                   u.name ,
                   c.id as companyId,
                   c.name as companyName,
                   c.ref_user_id as refUserId,
                   c.company_name_english as companyNameEnglish
               from user u
            left join  company c  on u.id = c .ref_user_id ShardingSphere-SQL.log[89]





分庫查詢
Actual SQL: ds0 ::: 
select  ^^^ from user_1 u left join  company_1 c  on u.id = c .ref_user_id               
select  ^^^ from user_0 u left join  company_0 c  on u.id = c .ref_user_id             


Actual SQL: ds1 ::: 
select  ^^^ from user_1 u left join  company_1 c  on u.id = c .ref_user_id      
select  ^^^ from user_0 u left join  company_0 c  on u.id = c .ref_user_id 

2.3、默認數據源,配合數據源看

默認數據源指定(不分庫的表)

默認數據源指定(不分庫的表)
spring.shardingsphere.sharding.default-data-source-name=ds0

2.4、配置廣播表

爲了防止跨庫查,可以將那些永遠不會改變的表。在每個庫中複製一份。一般適用於配置類的數據,(如果插入數據,會向所有的數據庫同時進行插入)

# 配置廣播表(爲了防止跨庫查,可以將那些永遠不會改變的表。在每個庫中複製一份。一般適用於配置類的數據,(如果插入數據,會向所有的數據庫同時進行插入)
spring.shardingsphere.sharding.broadcast-tables=demo_entity

感興趣的,歡迎添加博主微信

哈,博主很樂意和各路好友交流,如果滿意,請打賞博主任意金額,感興趣的在微信轉賬的時候,備註您的微信或者其他聯繫方式。添加博主微信哦。

請下方留言吧。可與博主自由討論哦

微信 微信公衆號 支付寶
微信 微信公衆號 支付寶
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章