本文基于shardingsphere-jdbc-core-spring-boot-starter 5.0.0,请注意不同版本的sharding-jdbc配置可能有不一样的地方,本文不一定适用于其它版本
相关的maven配置如下:
org.springframework.boot
spring-boot-starter-data-jpa
org.apache.shardingsphere
shardingsphere-jdbc-core-spring-boot-starter
5.0.0
mysql
mysql-connector-java
以下为单库分表的配置,根据对象的trade_no字段hash后mod进行分片,把数据分散到12个表中
spring:
shardingsphere:
datasource: ##数据源配置
ds0:
driver-class-name: com.mysql.jc.jdbc.Driver
jdbc-url: jdbc:mysql://...
password: ...
type: com.zaxxer.hikari.HikariDataSource
username: root
names: ds0
mode:
type: Memory
props:
sql-show: false ##为true时会打印sharding-jdbc生成的逻辑sql跟实际执行语句
rules: ##分片规则配置
sharding:
binding-tables:
- trade_info
sharding-algorithms:
trade-info-inline: #分片算法配置
props:
sharding-count: '12'
type: HASH_MOD
tables:
trade_info:
actual-data-nodes: ds0.trade_info_$->{0..11}
table-strategy:
standard:
sharding-algorithm-name: trade-info-inline ##使用的分片算法名
sharding-column: trade_no ##分片键
jpa提供了TABLE(使用一个特定的数据库表格来保存主键,在使用时从该表取数据做为主键)、SEQUENCE(由底层数据库的序列来生成主键,需要数据库支持序列)、IDENTITY(由数据库自动生成主键,主要在自增ID列使用 )三种生成主键值的策略。但对于分库分表来讲都不太适用,所以自定义了一个使用雪花算法来生成主键值
public class SnowFlakeIdGenerator implements IdentifierGenerator {
@Override
public Serializable generate(SharedSessionContractImplementor sharedSessionContractImplementor, Object o) throws HibernateException {
return SnowFlakeUtil.nextId();
}
@Override
public boolean supportsJdbcBatchInserts() {
return true;
}
}
实体类id的配置
@Id
@GenericGenerator(name = "snowflake",strategy = "com.****.****.****.SnowFlakeIdGenerator")
@GeneratedValue(generator = "snowflake")
private Long id;
配置完后,试了下新增、删除、查询都没有问题,但更新记录的时候出错了,报错信息为ShardingSphereException: Can not update sharding key, logic table: [**], column: [**]。从报错信息看来是因为我更新了原有记录的分片键,奇怪的是我并没有更新分片键,调用栈中最开始出错的代码如下:
public void preValidate(ShardingRule shardingRule, SQLStatementContext sqlStatementContext, List