(二)ShardingSphere入门水平切分

之前已经搭建好了基本的项目结构,下面开始数据库水平的切分,ShardingSphereJDBC是一个分表分库整合工具,他只帮你完成在分表分库之后的数据整理汇总等工作,不能帮你进行分表分库,比如你已经有数据库了想通过ShardingSphereJDBC进行分库是不行的。不过最新的4.1.0版本的ShardingSphere提出了ShardingSphere-Scaling用于做数据库分片迁移,目前处于alpha开发阶段,未来应该会有更方便的数据库切分解决方案。

单库水平切分

#  单库水平切分
spring:
  shardingsphere:
    # 所有数据库的别名
    datasource:
      names: ss1
      # 具体数据库的配置信息
      ss1:
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://localhost:3306/ss1?serverTimezone=Asia/Shanghai
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: root
        password: admin
    # 分表分库策略
    sharding:
      # 需要分表的策略
      tables:
        # 表名前缀 采坑这里必须是user 不能是user_ user_会报找不到表切分失败
        user:
	# 这里写实际的表明 比如 表 user_0 和 user_1 则user_$->{0..1} 或者user_$->{0..1..2}
          actual-data-nodes: ss1.user_$->{0..1}
          # 主键生成规则 默认使用雪花算法
          key-generator:
            column: id
            type: SNOWFLAKE
          # 分表策略
          table-strategy:
            inline:
              # 数据表达式计算 这里是为 id % 2 ==0 就是user_0 如果 id % 2==1 则user_id
              algorithm-expression: user_$->{id % 2}
              sharding-column: id
    props:
      sql:
      # 打印实际生成SQL
        show: true
  main:
    allow-bean-definition-overriding: true
@RunWith(SpringRunner.class)
@SpringBootTest
public class SingleDataBaseHorizontalTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert() {
        IntStream.range(0, 10).forEach(i -> {
            User user = new User();
            user.setName("name" + i);
            user.setAge(10 + i);
            userMapper.insert(user);
        });
    }

    @Test
    public void testFind(){
        userMapper.selectList(null).forEach(System.out::println);
    }

    @Test
    public void testFindByCondition(){
        userMapper.selectList(Wrappers.lambdaQuery(User.class).ge(User::getAge,15)).forEach(System.out::println);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qZ1zKbxB-1591667416501)(C:\Users\denglw\AppData\Roaming\Typora\typora-user-images\image-20200608175258343.png)]

user_0表中所有的id都是偶数,反之user_1的id都是奇数,此时已经实现了对单数据库的水平切分

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JRSaUiXu-1591667416504)(C:\Users\denglw\AppData\Roaming\Typora\typora-user-images\image-20200608175309719.png)]

多库的水平切分

#  单库水平切分
spring:
  shardingsphere:
    # 所有数据库的别名
    datasource:
      # 配置多个数据源
      names: ss1,ss2
      # 具体数据库的配置信息
      ss1:
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://localhost:3306/ss1?serverTimezone=Asia/Shanghai
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: root
        password: admin
      ss2:
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://localhost:3306/ss2?serverTimezone=Asia/Shanghai
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: root
        password: admin
    # 分表分库策略
    sharding:
      # 需要分表的策略
      tables:
        # 表名前缀
        user:
          actual-data-nodes: ss$->{1..2}.user_$->{0..1}
          # 主键生成规则 默认使用雪花算法
          key-generator:
            column: id
            type: SNOWFLAKE
           # 分库策略 与分表策略配置类似
          database-strategy:
            inline:
              shardingColumn: id
              algorithmExpression: ss${id % 2 + 1}
          # 分表策略
          table-strategy:
            inline:
              # 数据表达式计算 这里是为 id % 2 ==0 就是user_0 如果 id % 2==1 则user_1
              algorithm-expression: user_$->{id % 2}
              sharding-column: id

    props:
      # 实际生成SQL
      sql:
        show: true
  main:
    allow-bean-definition-overriding: true
@RunWith(SpringRunner.class)
@ActiveProfiles("multipleDatasourceHorizaontal")
@SpringBootTest
public class MultipleDataBaseHorizontalTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert() {
        IntStream.range(0, 10).forEach(i -> {
            User user = new User();
            user.setName("name" + i);
            user.setAge(10 + i);
            userMapper.insert(user);
        });
    }

    @Test
    public void testFind(){
        userMapper.selectList(null).forEach(System.out::println);
    }

    @Test
    public void testFindByCondition(){
        userMapper.selectList(Wrappers.lambdaQuery(User.class).ge(User::getAge,15)).forEach(System.out::println);
    }
}

运行测试发现所有偶数id的数据都会加在ss1数据库中的user_0表中

所有奇数id的数据会保存在ss2表中的user_1表中

猜你喜欢

转载自blog.csdn.net/woshiwjma956/article/details/106634719