spring boot使用sharding jdbc的配置方式
本文介绍了springboot使用shardingjdbc的配置方式,分享给大家,具体如下:
说明
要排除DataSourceAutoConfiguration,否则多数据源无法配置
@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
publicclassApplication{
publicstaticvoidmain(String[]args){
SpringApplication.run(Application.class,args);
}
}
配置的多个数据源交给sharding-jdbc管理,sharding-jdbc创建一个DataSource数据源提供给mybatis使用
官方文档:http://shardingjdbc.io/index_zh.html
步骤
配置多个数据源,数据源的名称最好要有一定的规则,方便配置分库的计算规则
@Bean(initMethod="init",destroyMethod="close",name="dataSource0")
@ConfigurationProperties(prefix="spring.datasource")
publicDataSourcedataSource0(){
returnnewDruidDataSource();
}
@Bean(initMethod="init",destroyMethod="close",name="dataSource1")
@ConfigurationProperties(prefix="spring.datasource2")
publicDataSourcedataSource1(){
returnnewDruidDataSource();
}
配置数据源规则,即将多个数据源交给sharding-jdbc管理,并且可以设置默认的数据源,当表没有配置分库规则时会使用默认的数据源
@Bean
publicDataSourceRuledataSourceRule(@Qualifier("dataSource0")DataSourcedataSource0,
@Qualifier("dataSource1")DataSourcedataSource1){
MapdataSourceMap=newHashMap<>();
dataSourceMap.put("dataSource0",dataSource0);
dataSourceMap.put("dataSource1",dataSource1);
returnnewDataSourceRule(dataSourceMap,"dataSource0");
}
配置数据源策略和表策略,具体策略需要自己实现
@Bean
publicShardingRuleshardingRule(DataSourceRuledataSourceRule){
//表策略
TableRuleorderTableRule=TableRule.builder("t_order")
.actualTables(Arrays.asList("t_order_0","t_order_1"))
.tableShardingStrategy(newTableShardingStrategy("order_id",newModuloTableShardingAlgorithm()))
.dataSourceRule(dataSourceRule)
.build();
TableRuleorderItemTableRule=TableRule.builder("t_order_item")
.actualTables(Arrays.asList("t_order_item_0","t_order_item_1"))
.tableShardingStrategy(newTableShardingStrategy("order_id",newModuloTableShardingAlgorithm()))
.dataSourceRule(dataSourceRule)
.build();
//绑定表策略,在查询时会使用主表策略计算路由的数据源,因此需要约定绑定表策略的表的规则需要一致,可以一定程度提高效率
ListbindingTableRules=newArrayList();
bindingTableRules.add(newBindingTableRule(Arrays.asList(orderTableRule,orderItemTableRule)));
returnShardingRule.builder()
.dataSourceRule(dataSourceRule)
.tableRules(Arrays.asList(orderTableRule,orderItemTableRule))
.bindingTableRules(bindingTableRules)
.databaseShardingStrategy(newDatabaseShardingStrategy("user_id",newModuloDatabaseShardingAlgorithm()))
.tableShardingStrategy(newTableShardingStrategy("order_id",newModuloTableShardingAlgorithm()))
.build();
}
创建sharding-jdbc的数据源DataSource,MybatisAutoConfiguration会使用此数据源
@Bean("dataSource")
publicDataSourceshardingDataSource(ShardingRuleshardingRule){
returnShardingDataSourceFactory.createDataSource(shardingRule);
}
需要手动配置事务管理器(原因未知)
//需要手动声明配置事务
@Bean
publicDataSourceTransactionManagertransactitonManager(@Qualifier("dataSource")DataSourcedataSource){
returnnewDataSourceTransactionManager(dataSource);
}
分库策略的简单实现,接口:DatabaseShardingAlgorithm
importjava.util.Collection; importjava.util.LinkedHashSet; importcom.dangdang.ddframe.rdb.sharding.api.ShardingValue; importcom.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm; importcom.google.common.collect.Range; /** *Createdbyfuwei.dengon2017年5月11日. */ publicclassModuloDatabaseShardingAlgorithmimplementsSingleKeyDatabaseShardingAlgorithm{ @Override publicStringdoEqualSharding(Collection databaseNames,ShardingValue shardingValue){ for(Stringeach:databaseNames){ if(each.endsWith(shardingValue.getValue()%2+"")){ returneach; } } thrownewIllegalArgumentException(); } @Override publicCollection doInSharding(Collection databaseNames,ShardingValue shardingValue){ Collection result=newLinkedHashSet<>(databaseNames.size()); for(Longvalue:shardingValue.getValues()){ for(StringtableName:databaseNames){ if(tableName.endsWith(value%2+"")){ result.add(tableName); } } } returnresult; } @Override publicCollection doBetweenSharding(Collection databaseNames,ShardingValue shardingValue){ Collection result=newLinkedHashSet<>(databaseNames.size()); Range range=(Range )shardingValue.getValueRange(); for(Longi=range.lowerEndpoint();i<=range.upperEndpoint();i++){ for(Stringeach:databaseNames){ if(each.endsWith(i%2+"")){ result.add(each); } } } returnresult; } }
分表策略的基本实现,接口:TableShardingAlgorithm
importjava.util.Collection; importjava.util.LinkedHashSet; importcom.dangdang.ddframe.rdb.sharding.api.ShardingValue; importcom.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm; importcom.google.common.collect.Range; /** *Createdbyfuwei.dengon2017年5月11日. */ publicclassModuloTableShardingAlgorithmimplementsSingleKeyTableShardingAlgorithm{ @Override publicStringdoEqualSharding(Collection tableNames,ShardingValue shardingValue){ for(Stringeach:tableNames){ if(each.endsWith(shardingValue.getValue()%2+"")){ returneach; } } thrownewIllegalArgumentException(); } @Override publicCollection doInSharding(Collection tableNames,ShardingValue shardingValue){ Collection result=newLinkedHashSet<>(tableNames.size()); for(Longvalue:shardingValue.getValues()){ for(StringtableName:tableNames){ if(tableName.endsWith(value%2+"")){ result.add(tableName); } } } returnresult; } @Override publicCollection doBetweenSharding(Collection tableNames,ShardingValue shardingValue){ Collection result=newLinkedHashSet<>(tableNames.size()); Range range=(Range )shardingValue.getValueRange(); for(Longi=range.lowerEndpoint();i<=range.upperEndpoint();i++){ for(Stringeach:tableNames){ if(each.endsWith(i%2+"")){ result.add(each); } } } returnresult; } }
至此,分库分表的功能已经实现
读写分离
读写分离需在创建DataSourceRule之前加一层主从数据源的创建
//构建读写分离数据源,读写分离数据源实现了DataSource接口,可直接当做数据源处理.
//masterDataSource0,slaveDataSource00,slaveDataSource01等为使用DBCP等连接池配置的真实数据源
DataSourcemasterSlaveDs0=MasterSlaveDataSourceFactory.createDataSource("ms_0",
masterDataSource0,slaveDataSource00,slaveDataSource01);
DataSourcemasterSlaveDs1=MasterSlaveDataSourceFactory.createDataSource("ms_1",
masterDataSource1,slaveDataSource11,slaveDataSource11);
//构建分库分表数据源
MapdataSourceMap=newHashMap<>(2);
dataSourceMap.put("ms_0",masterSlaveDs0);
dataSourceMap.put("ms_1",masterSlaveDs1);
//通过ShardingDataSourceFactory继续创建ShardingDataSource
强制使用主库时
HintManagerhintManager=HintManager.getInstance(); hintManager.setMasterRouteOnly(); //继续JDBC操作
强制路由
- 使用ThreadLocal机制实现,在执行数据库操作之前通过HintManager改变用于计算路由的值
- 设置HintManager的时候分库和分表的策略必须同时设置,并且设置后需要路由的表都需要设置用于计算路由的值。比如强制路由后需要操作t_order和t_order_item两个表,那么两个表的分库和分表的策略都需要设置
HintManagerhintManager=HintManager.getInstance();
hintManager.addDatabaseShardingValue("t_order","user_id",1L);
hintManager.addTableShardingValue("t_order","order_id",order.getOrderId());
hintManager.addDatabaseShardingValue("t_order_item","user_id",1L);
hintManager.addTableShardingValue("t_order_item","order_id",order.getOrderId());
事务
- sharding-jdbc-transaction实现柔性事务(默认提供了基于内存的事务日志存储器和内嵌异步作业),可结合elastic-job(sharding-jdbc-transaction-async-job)实现异步柔性事务
- 没有与spring结合使用的方式,需要自己封装
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。