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结合使用的方式,需要自己封装
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。