前面几篇文章我们都是通过yml配置文件的方式,简单实现了 inline模式下的分库分表。 通过yml的方式,我们需要在配置文件中配置数据源和分库分表的策略表达式。那么如果我不想在配置文件中写如此冗长的配置,能否采用java config 的方式实现呢。肯定是可以的。
本篇文章我们就来介绍通过java config的方式来重新实现inline模式下的分库分表。本次代码案例我们在git脚手架里的 sharding-inline-java 的module下进行。(git地址参看第一篇文章)
首先还是先依赖 sharding-biz, 主要是配置文件。
首先在config包下创建 MybatisPlusConfig 配置类,内容如下; (注意:有一个ConditionOnBean注解,用来限制类的加载顺序,防止出错)
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "cn.cestc.biz.mapper")
@ConditionalOnBean(value= DataSource.class)
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setLimit(-1);
return paginationInterceptor;
}
}
第二步,添加一个 shardingJdbc的配置类,用来替换原来的yml
import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.apache.shardingsphere.spring.boot.util.DataSourceUtil;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;
/**
* @className: ShardingDataSourceConfiguration
* @description:
* @author: sh.Liu
* @date: 2020-11-03 19:23
*/
@Configuration
@MapperScan(basePackages = "cn.cestc.biz.mapper")
public class ShardingDataSourceConfiguration {
@Bean("shardingDataSource")
public DataSource getShardingDataSource() throws SQLException, ReflectiveOperationException {
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
// 广播表
List<String> broadcastTables = new LinkedList<>();
broadcastTables.add("t_user");
broadcastTables.add("t_address");
shardingRuleConfig.setBroadcastTables(broadcastTables);
// 默认策略
shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("user_id", "ds0"));
shardingRuleConfig.setDefaultTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("user_id", "t_order_${user_id % 4 + 1}"));
// 获取user表的分片规则配置
TableRuleConfiguration userInfoTableRuleConfiguration = getUserInfoTableRuleConfiguration();
shardingRuleConfig.getTableRuleConfigs().add(userInfoTableRuleConfiguration);
Properties props = new Properties();
props.put("sql.show", "true");
return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), shardingRuleConfig, props);
}
/**
* 配置真实数据源
* @return 数据源map
*/
private Map<String, DataSource> createDataSourceMap() throws ReflectiveOperationException {
Map<String, DataSource> dataSourceMap = new HashMap<>();
Map<String, Object> dataSourceProperties = new HashMap<>();
dataSourceProperties.put("DriverClassName", "com.mysql.jdbc.Driver");
dataSourceProperties.put("jdbcUrl", "jdbc:mysql://localhost:3306/ds0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8");
dataSourceProperties.put("username", "root");
dataSourceProperties.put("password", "root");
DataSource dataSource1 = DataSourceUtil.getDataSource("com.zaxxer.hikari.HikariDataSource", dataSourceProperties);
Map<String, Object> dataSourceProperties2 = new HashMap<>();
dataSourceProperties2.put("DriverClassName", "com.mysql.jdbc.Driver");
dataSourceProperties2.put("jdbcUrl", "jdbc:mysql://localhost:3306/ds1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8");
dataSourceProperties2.put("username", "root");
dataSourceProperties2.put("password", "root");
DataSource dataSource2 = DataSourceUtil.getDataSource("com.zaxxer.hikari.HikariDataSource", dataSourceProperties2);
dataSourceMap.put("ds0",dataSource1);
dataSourceMap.put("ds1",dataSource2);
return dataSourceMap;
}
/**
* 配置user表的分片规则
*
* @return ser表的分片规则配置对象
*/
private TableRuleConfiguration getUserInfoTableRuleConfiguration() {
// 为user表配置数据节点
TableRuleConfiguration ruleConfiguration = new TableRuleConfiguration("t_order", "ds0.t_order_$->{1..4}");
// 设置分片键
String shardingKey = "user_id";
// 为user表配置分库分片策略及分片算法
ruleConfiguration.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration(shardingKey, "ds$->{user_id % 2}"));
// 为user表配置分表分片策略及分片算法
ruleConfiguration.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration(shardingKey, "t_order_${user_id % 4 + 1}"));
ruleConfiguration.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "order_id"));
return ruleConfiguration;
}
}
这个类中,配置了数据源的集合,同时在getUserInfoTableRuleConfiguration 方法中配置了order表的分库分表策略,和之前yml文件中的配置都是对应的,如果有多个表,添加多个方法,在getShardingDataSource 方法中添加(add) 多个策略即可。
最关键的是启动类,需要排除一个类 @SpringBootApplication(exclude = {SpringBootConfiguration.class}), 注意的是 SpringBootConfiguration要选择的是 shardingjdbc包下面的这个类:代码如下
import org.apache.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @className: ShardingInlineJavaApplication
* @description:
* @author: sh.Liu
* @date: 2020-11-15 10:57
*/
@SpringBootApplication(exclude = {SpringBootConfiguration.class})
public class ShardingInlineJavaApplication {
public static void main(String[] args) {
SpringApplication.run(ShardingInlineJavaApplication.class, args);
}
}
好了,万事具备,接下来写一个测试的Controller, 测试一下分库分表的策略是否生效即可。
关于inline模式的分库分表到这里就告一段落了,在这一部分中,我们详细介绍了inline模式如何分库,如何分表,以及如何使用java config 实现。 下一部分我们重点研究下一种策略, standard标准策略的分库分表。