Shardingsphere的分库分表+读写分离+分页条件查询

Shardingsphere的分库分表与读写分离

导入依赖

   <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintagegroupId>
                    <artifactId>junit-vintage-engineartifactId>
                exclusion>
            exclusions>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>8.0.28version>
        dependency>
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <version>3.5.1version>
        dependency>
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-generatorartifactId>
            <version>3.5.2version>
        dependency>
        <dependency>
            <groupId>org.freemarkergroupId>
            <artifactId>freemarkerartifactId>
            <version>2.3.31version>
        dependency>
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druidartifactId>
            <version>1.2.10version>
        dependency>
        <dependency>
            <groupId>org.apache.shardingspheregroupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starterartifactId>
            <version>5.1.1version>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>

创建数据库,前提是两个服务器做好了主从复制

Shardingsphere的分库分表+读写分离+分页条件查询_第1张图片

spring:
  shardingsphere:
    mode:
      type: Memory                                                   # 内存模式,元数据保存在当前进程中
    datasource:
      names: master$->{0..1},slave$->{0..1}
      master0:                                                # 跟上面的数据源对应
        type: com.alibaba.druid.pool.DruidDataSource                 # 连接池
        url: jdbc:mysql://xxxxxx/test0                       # 连接url
        username: root
        password: 123456
      master1:                                                  # 跟上面的数据源对应
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://xxxxxx/test1
        username: root
        password: 123456
      slave0:                                                   # 跟上面的数据源对应
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://xxxxxx/test0
        username: root
        password: 123456
      slave1:                                                   # 跟上面的数据源对应
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://xxxxxx/test1
        username: root
        password: 123456

    rules:                                                           # 配置分库分表以及读写分离的规则
      sharding:                                                      # 配置分库分表规则
        tables:
          user:                                                      # 这个可以随便取,问题不大
            actual-data-nodes: master$->{0..1}.user$->{0..2}    # 实际节点名称,格式为 库名$->{0..n1}.表名$->{0..n2}
              # 其中n1、n2分别为库数量-1和表数量-1
              # 也可以使用${0..n1}的形式,但是会与Spring属性文件占位符冲突
            # 所以使用$->{0..n1}的形式

            database-strategy:                                       # 分库策略
              standard:                                              # 标准分库策略
                sharding-column: age                                 # 分库列名
                sharding-algorithm-name: age-mod                     # 分库算法名字
            table-strategy:                                          # 分表策略
              standard:                                              # 标准分表策略
                sharding-column: id                                  # 分表列名
                sharding-algorithm-name: id-mod                      # 分表算法名字

        sharding-algorithms:                                         # 配置分库和分表的算法
          age-mod:                                                   # 分库算法名字
            type: MOD                                                # 算法类型为取模
            props:                                                   # 算法配置的键名,所有算法配置都需要在props下
              sharding-count: 2                                      # 分片数量
          id-mod:                                                    # 分表算法名字
            type: MOD                                                # 算法类型为取模
            props:                                                   # 算法配置的键名,所有算法配置都需要在props下
              sharding-count: 3                                      # 分片数量

      readwrite-splitting:                                           # 配置读写分离规则
        data-sources:                                                # 数据源
          master0:                                              # 这个可以随便取,带有区分意义即可,比如这里表示的是主库test0的规则
            type: Static                                             # 静态类型
            load-balancer-name: round_robin                          # 负载均衡算法名字
            props:                                                   # 具体读写数据源需要配置在props下
              write-data-source-name: master0                   # 写数据源
              read-data-source-names: slave0                    # 读数据源
          master1:
            type: Static                                             # 静态类型
            load-balancer-name: round_robin                          # 负载均衡算法名字
            props:                                                   # 具体读写数据源需要配置在props下
              write-data-source-name: master1                   # 写数据源
              read-data-source-names: slave1                    # 读数据源
        load-balancers:                                              # 负载均衡配置
          round_robin:                                               # 跟上面负载均衡算法的名字对应
            type: ROUND_ROBIN                                        # 负载均衡算法
    props:
      sql-show: true                                                 # 打印SQL

测试

package com.ycz.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ycz.entity.User;
import com.ycz.service.IUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Random;

@RestController
@RequestMapping("/user")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class UserController {
    private final IUserService userService;

    @GetMapping("/insert")
    public boolean insert() {
        User user = new User();
        user.setName("啊实打实的撒");
        user.setAge(new Random().nextInt(100)+1);
        System.out.println(user);
        return userService.save(user);
    }

    @GetMapping("/select")
    public List<User> select() {
        return userService.list();
    }

    @GetMapping("/select/{id}")
    public Object getById(@PathVariable String id){
        return userService.getById(id);
    }

    @GetMapping("/update/{id}")
    public Object update(@PathVariable String id){
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(User::getName , "大萨达十大");
        updateWrapper.eq("id" , id);
        return userService.update(updateWrapper);
    }
}

插入

Shardingsphere的分库分表+读写分离+分页条件查询_第2张图片

可以发现写的是主库 master

在这里插入图片描述

3311

Shardingsphere的分库分表+读写分离+分页条件查询_第3张图片

3312
Shardingsphere的分库分表+读写分离+分页条件查询_第4张图片

查询

Shardingsphere的分库分表+读写分离+分页条件查询_第5张图片

可以发现读的是从库

在这里插入图片描述

分页条件查询

yml

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath*:com/ycz/**/xml/*Mapper.xml

配置config

package com.ycz.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description:
 * @Author: Alex
 * @Date 2022-06-29-21:58
 * @Version: V1.0
 **/
@Configuration
public class MybatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

 @GetMapping("/select")
    public Object select(@RequestParam(value = "pageNo" ,required = false , defaultValue = "0")Integer pageNo ,
                         @RequestParam(value ="pageSize" ,required = false , defaultValue = "5")Integer pageSize) {

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("age");
        Page<User> page = new Page<>(pageNo  , pageSize);

        IPage<User> pageList = userService.page(page ,queryWrapper);

        return pageList;
    }

查询结果:

{
    "records": [
        {
            "id": "1540666225414160385",
            "name": "test1_user0_2",
            "age": 89
        },
        {
            "id": "1540665503343718401",
            "name": "test1_user0_1",
            "age": 85
        },
        {
            "id": "1540666229851734017",
            "name": "test1_user2_2",
            "age": 81
        },
        {
            "id": "1540665515347816450",
            "name": "test0_user1_1",
            "age": 78
        },
        {
            "id": "1540669670086983682",
            "name": "test0_user1_3",
            "age": 78
        }
    ],
    "total": 15,
    "size": 5,
    "current": 1,
    "orders": [],
    "optimizeCountSql": true,
    "hitCount": false,
    "countId": null,
    "maxLimit": null,
    "searchCount": true,
    "pages": 3
}

我们看看其sql语句

sql语句是这样的
slave0 ::: SELECT  id,name,age  FROM user0 ORDER BY age DESC LIMIT ? ::: [5]
slave0 ::: SELECT  id,name,age  FROM user1 ORDER BY age DESC LIMIT ? ::: [5]
slave0 ::: SELECT  id,name,age  FROM user2 ORDER BY age DESC LIMIT ? ::: [5]
slave1 ::: SELECT  id,name,age  FROM user0 ORDER BY age DESC LIMIT ? ::: [5]
slave1 ::: SELECT  id,name,age  FROM user1 ORDER BY age DESC LIMIT ? ::: [5]
slave1 ::: SELECT  id,name,age  FROM user2 ORDER BY age DESC LIMIT ? ::: [5]

sharding JDBC 默认使用limit进行分页,在不指定路由字段时,分页将会全库全表全数据捞取,然后进行排序。

你可能感兴趣的:(mybatis,java,spring,boot)