携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情
一、分表:sharding jdbc
1. 引入依赖
<properties>
<sharding-sphere.version>4.1.0</sharding-sphere.version>
</properties>
<!-- 分库分表:https://mvnrepository.com/artifact/org.apache.shardingsphere/sharding-jdbc-spring-boot-starter -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>${sharding-sphere.version}</version>
</dependency>
2. 配置分表信息
spring:
shardingsphere:
datasource:
names: precious
precious:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://ip:port/xxx?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true
username: username
password: password
props:
# 日志显示SQL
sql.show: true
sharding:
tables:
# 分表:20
sys_user:
# 真实表 sys_user_0
actualDataNodes: precious.sys_user_$->{0..19}
# 分库策略
databaseStrategy:
none:
# 分表策略
tableStrategy:
inline:
shardingColumn: grading_result_key
# 分片算法行表达式,需符合groovy语法 '& Integer.MAX_VALUE' 位运算使hash值为正数
algorithmExpression: sys_user_$->{(grading_result_key.hashCode() & Integer.MAX_VALUE) % 20}
二、sharding jdbc对一些语法不兼容
sharding jdbc 不支持insert into ... select, case when等,因为涉及到分表的语句不是很多,可以针对性的改一改。但是对于没有涉及到分表的语句,也有同样的限制,这样涉及面就广了。
现在想要对分表的SQL使用 sharding jdbc数据源,对不涉及到分表的SQL,使用普通数据源。 这时,需要集成多数据源。
三、多数据源:dynamic-datasource
baomidou的dynamic-datasource团队提交了一个相同需求的PR:
按照其思路,稍微改造了下,如下:
1. 引入依赖
<!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-spring-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.1.1</version>
</dependency>
2. 将sharding jdbc数据源加入到多数据源中
@Configuration
@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class,
SpringBootConfiguration.class})
public class DataSourceConfiguration {
/**
* 分表数据源名称
*/
private static final String SHARDING_DATA_SOURCE_NAME = "sharding";
@Autowired
private DynamicDataSourceProperties properties;
/**
* shardingjdbc有四种数据源,需要根据业务注入不同的数据源
*
* <p>1. 未使用分片, 脱敏的名称(默认): shardingDataSource;
* <p>2. 主从数据源: masterSlaveDataSource;
* <p>3. 脱敏数据源:encryptDataSource;
* <p>4. 影子数据源:shadowDataSource
*
*/
@Lazy
@Resource(name = "shardingDataSource")
AbstractDataSourceAdapter shardingDataSource;
@Bean
public DynamicDataSourceProvider dynamicDataSourceProvider() {
Map<String, DataSourceProperty> datasourceMap = properties.getDatasource();
return new AbstractDataSourceProvider() {
@Override
public Map<String, DataSource> loadDataSources() {
Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap);
// 将 shardingjdbc 管理的数据源也交给动态数据源管理
dataSourceMap.put(SHARDING_DATA_SOURCE_NAME, shardingDataSource);
return dataSourceMap;
}
};
}
/**
* 将动态数据源设置为首选的
* 当spring存在多个数据源时, 自动注入的是首选的对象
* 设置为主要的数据源之后,就可以支持shardingjdbc原生的配置方式了
*
* @return
*/
@Primary
@Bean
public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
dataSource.setPrimary(properties.getPrimary());
dataSource.setStrict(properties.getStrict());
dataSource.setStrategy(properties.getStrategy());
dataSource.setProvider(dynamicDataSourceProvider);
dataSource.setP6spy(properties.getP6spy());
dataSource.setSeata(properties.getSeata());
return dataSource;
}
}
3. 增加多数据源配置
在第2步,我们指定了shardingsphere数据源的名称为:sharding
spring:
datasource:
# 动态数据源配置
dynamic:
datasource:
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/xxx?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true
username: username
password: password
# 指定默认数据源名称
primary: sharding
# 分表配置
shardingsphere:
datasource:
names: precious
precious:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://ip:3306/xxx?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true
username: username
password: password
props:
# 日志显示SQL
sql.show: true
sharding:
tables:
# 分表:20
sys_user:
# 真实表 sys_user_0
actualDataNodes: precious.sys_user_$->{0..19}
# 分库策略
databaseStrategy:
none:
# 分表策略
tableStrategy:
inline:
shardingColumn: grading_result_key
# 分片算法行表达式,需符合groovy语法 '& Integer.MAX_VALUE' 位运算使hash值为正数
algorithmExpression: sys_user_$->{(grading_result_key.hashCode() & Integer.MAX_VALUE) % 20}
这里将默认数据源指定为了aml_sharding(shardingsphere数据源)。
4. 使用
在不需要分表的service方法上加上@DS("master"),即可切换为普通数据源。
@Service
@Slf4j
public class SysUserServiceImpl extends SysUserService {
@Override
@DS("master")
public SysUserUpdateDTO test(DTO dto) throws Exception {
return super.test(dto);
}
}
注意
也可以将默认数据源指定为master普通数据源,在需要分表的service方法上加@DS("aml_sharding"),使用shardingsphere分表数据源。这里可以按照改动量来指定哪种数据源为默认数据源。