sharding-jdbc是客户端代理的数据库中间件;它和MyCat最大的不同是sharding-jdbc支持库内分表。
在两台不同的主机上分别都创建了sharding_order数据库,库中都有t_order_1和t_order_2两张表。
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.1.1</version>
</dependency>
在application.properties配置文件中进行数据源配置、分库分表规则配置
#shardingsphere数据源配置
spring.shardingsphere.datasource.names=ds0,ds1
#数据源配置
spring.shardingsphere.dataSource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.dataSource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.dataSource.ds0.jdbcUrl=jdbc:mysql://192.168.200.215:3306/sharding_order?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.dataSource.ds0.username=root
spring.shardingsphere.dataSource.ds0.password=root
spring.shardingsphere.dataSource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.dataSource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.dataSource.ds1.jdbcUrl=jdbc:mysql://192.168.200.225:3306/sharding_order?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.dataSource.ds1.username=root
spring.shardingsphere.dataSource.ds1.password=root
#shardingsphere数据节点分片规则
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds$->{0..1}.t_order_$->{1..2}
#数据源分片规则,决定数据落在哪个库
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression=ds$->{user_id % 2}
#表分片规则,决定数据落在哪个表
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{id % 2 + 1}
#逻辑表,mybatis中查询的时候需要使用逻辑表查询,不能使用具体的分片表
spring.shardingsphere.sharding.tables.t_order.logic-table=t_order
/**
* 测试分库分表
*/
@Test
public void test4() {
Order order = new Order();
order.setId(5);
order.setUserId(2);
order.setOrderStatus(1);
order.setOrderAmount(BigDecimal.valueOf(3000));
orderMapper.insert(order);
}
数据落在了215这台主机上的sharding_order数据库中的t_order_2表中;证明分库分表成功了。
由于有两张order表,t_order_1和t_order2;而且在单表中我们往往会设置主键自增,那么就会出现表中的id重复的问题,sharding-jdbc支持使用通过雪花算法生成uuid作为主键来解决这个问题。
#表分片规则
#标准表达式
spring.shardingsphere.sharding.tables.t_order.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.t_order.table-strategy.standard.precise-algorithm-class-name=com.sharding.jdbc.sharding.MySharding
#id生成规则,分布式全局id
spring.shardingsphere.sharding.tables.t_order.key-generator.column=id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=UUID
分片规则
/**
* @author DELL
* @version 1.0
* @description:精确分片规则
* @date 2023/11/26 13:34:36
*/
public class MySharding implements PreciseShardingAlgorithm<String> {
/**
*
* @param collection:表名
* @param preciseShardingValue:生成的uuid、逻辑表、字段名
* @return
*/
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
String id = preciseShardingValue.getValue();
int mode = id.hashCode() % collection.size();
String[] strings = collection.toArray(new String[0]);
System.out.println("strings:" + Arrays.toString(strings));
return strings[Math.abs(mode)];
}
}
这里要注意的是由于这里的id是sharding-jdbc帮我们生成的,所以调用mapper中方法的时候不能指定id,否则不会自动生成。
/**
* 测试生成uuid
*/
@Test
public void test5() {
Order order = new Order();
order.setUserId(3);
order.setOrderStatus(1);
order.setOrderAmount(BigDecimal.valueOf(3000));
orderMapper.insert(order);
}
如果报了这个错,大概率就是sql中指定了id。
Sharding value must implements Comparable.
uui的是有可能重复的,这里可以指定使用雪花算法生成uuid。雪花算法配置如下:
spring.shardingsphere.sharding.tables.t_order.key-generator.column=id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key-generator.props.worker.id=345
分片规则中的String需要改成Long。