spring boot使用sharding jdbc的配置方式

网友投稿 894 2023-03-03


spring boot使用sharding jdbc的配置方式

本文介绍了spring boot使用sharding jdbc的配置方式,分享给大家,具体如下:

说明

要排除DataSourceAutoConfiguration,否则多数据源无法配置

@SpringBootApplication

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

public class Application {

public static void main(String[] args) {

SpringApplicexJmVqtAwation.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")

public DataSource dataSource0(){

return new DruidDataSource();

}

@Bean(initMethod="init", destroyMethod="close", name="dataSource1")

@ConfigurationProperties(prefix = "spring.datasource2")

public DataSource dataSource1(){

return new DruidDataSource();

}

配置数据源规则,即将多个数据源交给sharding-jdbc管理,并且可以设置默认的数据源,当表没有配置分库规则时会使用默认的数据源

@Bean

public DataSourceRule dataSourceRule(@Qualifier("dataSource0") DataSource dataSource0,

@Qualifier("dataSource1") DataSource dataSource1){

Map dataSourceMap = new HashMap<>();

dataSourceMap.put("dataSource0", dataSource0);

dataSourceMap.put("dataSource1", dataSource1);

return new DataSourceRule(dataSourceMap, "dataSource0");

}

配置数据源策略和表策略,具体策略需要自己实现

@Bean

public ShardingRule shardingRule(DataSourceRule dataSourceRule){

//表策略

TableRule orderTableRule = TableRule.builder("t_order")

.actualTables(Arrays.asList("t_order_0", "t_order_1"))

.tableShardingStrategy(new TableShardingStrategy("order_id", new ModuloTableShardingAlgorithm()))

.dataSourceRule(dataSourceRule)

.build();

TableRule orderItemTableRule = TableRule.builder("t_order_item")

.actualTables(Arrays.asList("t_order_item_0", "t_order_item_1"))

.tableShardingStrategy(new TableShardingStrategy("order_id", new ModuloTableShardingAlgorithm()))

.dataSourceRule(dataSourceRule)

.build();

//绑定表策略,在查询时会使用主表策略计算路由的数据源,因此需要约定绑定表策略的表的规则需要一致,可以一定程度提高效率

List bindingTableRules = new ArrayList();

bindingTableRules.add(new BindingTableRule(Arrays.asList(orderTableRule, orderItemTableRule)));

return ShardingRule.builder()

.dataSourceRule(dataSourceRule)

.tableRules(Arrays.asList(orderTableRule, orderItemTableRule))

.bindingTableRules(bindingTableRules)

.databaseShardingStrategy(new DatabaseShardingStrategy("user_id", new ModuloDatabaseShardingAlgorithm()))

.tableShardingStrategy(new TableShardingStrategy("order_id", new ModuloTableShardingAlgorithm()))

.build();

}

创建sharding-jdbc的数据源DataSource,MybatisAutoConfiguration会使用此数据源

@Bean("dataSource")

public DataSource shardingDataSource(ShardingRule shardingRule){

return ShardingDataSourceFactory.createDataSource(shardingRule);

}

需要手动配置事务管理器(原因未知)

//需要手动声明配置事务

@Bean

public DataSourceTransactionManager transactitonManager(@Qualifier("dataSource") DataSource dataSource){

return new DataSourceTransactionManager(dataSource);

}

分库策略的简单实现,接口:DatabaseShardingAlgorithm

import java.util.Collection;

import java.util.LinkedHashSet;

import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;

import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm;

import com.google.common.collect.Range;

/**

* Created by fuwei.deng on 2017年5月11日.

*/

public class ModuloDatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm {

@Override

public String doEqualSharding(Collection databaseNames, ShardingValue shardingValue) {

for (String each : databaseNames) {

if (each.endsWith(shardingValue.getValue() % 2 + "")) {

return each;

}

}

throw new IllegalArgumentException();

}

@Override

public Collection doInSharding(Collection databaseNames, ShardingValue shardingValue) {

Collection result = new LinkedHashSet<>(databaseNames.size());

for (Long value : shardingValue.getValues()) {

for (String tableName : databaseNames) {

if (tableName.endsWith(value % 2 + "")) {

result.add(tableName);

}

}

}

return result;

}

@Override

public Collection doBetweenSharding(Collection databaseNames, ShardingValue shardingValue) {

Collection result = new LinkedHashSet<>(databaseNames.size());

Range range = (Range) shardingValue.getValueRange();

for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {

for (String each : databaseNames) {

if (each.endsWith(i % 2 + "")) {

result.add(each);

}

}

}

return result;

}

}

分表策略的基本实现,接口:TableShardingAlgorithm

imporhttp://t java.util.Collection;

import java.util.LinkedHashSet;

import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;

import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgohttp://rithm;

import com.google.common.collect.Range;

/**

* Created by fuwei.deng on 2017年5月11日.

*/

public class ModuloTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm {

@Override

public String doEqualSharding(Collection tableNames, ShardingValue shardingValue) {

for (String each : tableNames) {

if (each.endsWith(shardingValue.getValue() % 2 + "")) {

return each;

}

}

throw new IllegalArgumentException();

}

@Override

public Collection doInSharding(Collection tableNames, ShardingValue shardingValue) {

Collection result = new LinkedHashSet<>(tableNames.size());

for (Long value : shardingValue.getValues()) {

for (String tableName : tableNames) {

if (tableName.endsWith(value % 2 + "")) {

result.add(tableName);

}

}

}

return result;

}

@Override

public Collection doBetweenSharding(Collection tableNames, ShardingValue shardingValue) {

Collection result = new LinkedHashSet<>(tableNames.size());

Range range = (Range) shardingValue.getValueRange();

for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {

for (String each : tableNames) {

if (each.endsWith(i % 2 + "")) {

result.add(each);

}

}

}

return result;

}

}

至此,分库分表的功能已经实现

读写分离

读写分离需在创建DataSourceRule之前加一层主从数据源的创建

// 构建读写分离数据源, 读写分离数据源实现了DataSource接口, 可直接当做数据源处理.

// masterDataSource0, slaveDataSource00, slaveDataSource01等为使用DBCP等连接池配置的真实数据源

DataSource masterSlaveDs0 = MasterSlaveDataSourceFactory.createDataSource("ms_0",

masterDataSource0, slaveDataSource00, slaveDataSource01);

DataSource masterSlaveDs1 = MasterSlaveDataSourceFactory.createDataSource("ms_1",

masterDataSource1, slaveDataSource11, slaveDataSource11);

// 构建分库分表数据源

Map dataSourceMap = new HashMap<>(2);

dataSourceMap.put("ms_0", masterSlaveDs0);

dataSourceMap.put("ms_1", masterSlaveDs1);

// 通过ShardingDataSourceFactory继续创建ShardingDataSource

强制使用主库时

HintManager hintManager = HintManager.getInstance();

hintManager.setMasterRouteOnly();

// 继续JDBC操作

强制路由

使用ThreadLocal机制实现,在执行数据库操作之前通过HintManager改变用于计算路由的值

设置HintManager的时候分库和分表的策略必须同时设置,并且设置后需要路由的表都需要设置用于计算路由的值。比如强制路由后需要操作t_order和t_order_item两个表,那么两个表的分库和分表的策略都需要设置

HintManager hintManager = 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结合使用的方式,需要自己封装


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java实现基于JDBC操作mysql数据库的方法
下一篇:swiper移动端轮播插件(触碰图片之后停止轮播)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~