SpringBoot+ShardingSphere测试

286 阅读1分钟

1. 项目地址

Springboot-Shardingjdbc

2. 配置文件

# MyBatis配置
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.config-location=classpath:mybatis-config.xml

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://****:3306/ds0
spring.shardingsphere.datasource.ds0.username=****
spring.shardingsphere.datasource.ds0.password=****

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://****:3306/ds1
spring.shardingsphere.datasource.ds1.username=****
spring.shardingsphere.datasource.ds1.password=****

# 分片策略 (行表达式分片策略InlineShardingStrategy)
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds${user_id % 2}

# 分库算法 user_info,多库分表
# 只分库但没有分表 分库是真正有作用的,但是如果在一个库里进行了分表,意义不是很大。
#   如果针对同一个表,既分库又分表,比如ds0.user_info_0,ds0.user_info_1,ds1.user_info_0,ds1.user_info_1
#   如果针对useid进行模2为0落到ds0.user_info_0,为1落到ds1.user_info_1,则ds0.user_info_1,ds1.user_info_0就会用不到,对吧。
#   所以只分库不分表是很合理的,不管分的库是在同一个服务器还是不同的服务器都可以。
spring.shardingsphere.sharding.tables.user_info.actual-data-nodes=ds$->{0..1}.user_info
# 分片键
spring.shardingsphere.sharding.tables.user_info.databaseStrategy.inline.shardingColumn=user_id
# 分库的算法是用ds拼接[user_id模2]
spring.shardingsphere.sharding.tables.user_info.databaseStrategy.inline.algorithm-expression=ds${user_id % 2}
spring.shardingsphere.sharding.tables.user_info.key-generator.column=user_id
spring.shardingsphere.sharding.tables.user_info.key-generator.type=SNOWFLAKE

# 分库算法 t_order 多库分表
spring.shardingsphere.sharding.tables.t_order.databaseStrategy.inline.shardingColumn=order_id
spring.shardingsphere.sharding.tables.t_order.databaseStrategy.inline.algorithm-expression=ds${order_id % 2}
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds$->{0..1}.t_order

# 分库算法 t_order_item 多库分表
spring.shardingsphere.sharding.tables.t_order_item.databaseStrategy.inline.shardingColumn=order_id
spring.shardingsphere.sharding.tables.t_order_item.databaseStrategy.inline.algorithm-expression=ds${order_id % 2}
spring.shardingsphere.sharding.tables.t_order_item.actual-data-nodes=ds$->{0..1}.t_order_item

# 绑定表规则列表,防止关联查询出现笛卡尔积
spring.shardingsphere.sharding.binding-tables[0]=t_order,t_order_item

# 广播表
spring.shardingsphere.sharding.broadcast-tables=t_config

3. 测试

3.1 普通的user_id分片

//部分代码
public void insert() {
    for (int i = 1; i <= 100; i++) {
        UserInfo userInfo = new UserInfo();
        // userInfo.setUserId(userId); //会使用sharding-jdbc自带的生成的全局ID
        userInfo.setAccount("account" + i);
        userInfo.setPassword("password" + i);
        userInfo.setUserName("name" + i);
        userId++;
        userInfoMapper.insert(userInfo);
    }
}
执行insert方法:添加100条user_info数据(一个库中有50条)

image.png image.png 查询:

@Test
public void select(){
    UserInfo userInfo1= userService.getUserInfoByUserId(582609201549803521l);
    System.out.println("------userInfo1:"+userInfo1);
    
    UserInfo userInfo2= userService.getUserInfoByUserId(582609200694165504l);
    System.out.println("------userInfo2:"+userInfo2);
}

image.png image.png

3.2 绑定表(t_order,t_order_item)

//t_order新增
public void insert() {
    for (int i = 1; i <= 100; i++) {
        Order order = new Order();
        order.setOrderId(i);
        order.setUserId(i);
        orderId++;
        userId++;
        orderMapper.insert(order);
    }
}
//t_order_item新增
public void insert() {
    for (int i = 1; i <= 100; i++) {
        OrderItem orderItem = new OrderItem();
        orderItem.setItemId(i);
        orderItem.setOrderId(i);
        orderItem.setUserId(i);
        orderItemMapper.insert(orderItem);
    }
}

image.png image.png

注意这个配置:
# 绑定表规则列表,防止关联查询出现笛卡尔积
spring.shardingsphere.sharding.binding-tables[0]=t_order,t_order_item

如果不配置它会出现 笛卡尔积,什么叫笛卡尔积?假如有 2 个数据库,两张表要相互关联,两张表又各有分表,那 么 SQL 的执行路径就是 222=8 种。如果针对同一个表,既分库又分表,比如

ds0.order0,ds0.order1,
ds0.order_item0,ds0.order_item1

ds1.order_0,ds1.order_1,
ds1.order_item_0,ds1.order_item_1

会出现,多出几次无效查询 image.png 如果配置了绑定规则, image.png

3.3 全局表

//插入10条数据
public void insert() {
    for (int i = 1; i <= 10; i++) {
        Config config = new Config();
        config.setConfigId(i);
        config.setParaName("name"+i);
        config.setParaValue("value"+i);
        config.setParaDesc("desc"+i);
        configId++;
        configMapper.insert(config);
    }
}

image.png image.png