spring boot使用sharding jdbc的配置方式

2025-05-29 0 80

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

说明

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

?

1

2

3

4

5

6

7

8

9
@SpringBootApplication

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}

配置的多个数据源交给sharding-jdbc管理,sharding-jdbc创建一个DataSource数据源提供给mybatis使用

官方文档:http://shardingjdbc.io/index_zh.html

步骤

配置多个数据源,数据源的名称最好要有一定的规则,方便配置分库的计算规则

?

1

2

3

4

5

6

7

8

9

10

11
@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管理,并且可以设置默认的数据源,当表没有配置分库规则时会使用默认的数据源

?

1

2

3

4

5

6

7

8
@Bean

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

@Qualifier("dataSource1") DataSource dataSource1){

Map<String, DataSource> dataSourceMap = new HashMap<>();

dataSourceMap.put("dataSource0", dataSource0);

dataSourceMap.put("dataSource1", dataSource1);

return new DataSourceRule(dataSourceMap, "dataSource0");

}

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24
@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<BindingTableRule> bindingTableRules = new ArrayList<BindingTableRule>();

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会使用此数据源

?

1

2

3

4
@Bean("dataSource")

public DataSource shardingDataSource(ShardingRule shardingRule){

return ShardingDataSourceFactory.createDataSource(shardingRule);

}

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

?

1

2

3

4

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

@Bean

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

return new DataSourceTransactionManager(dataSource);

}

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50
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<Long> {

@Override

public String doEqualSharding(Collection<String> databaseNames, ShardingValue<Long> shardingValue) {

for (String each : databaseNames) {

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

return each;

}

}

throw new IllegalArgumentException();

}

@Override

public Collection<String> doInSharding(Collection<String> databaseNames, ShardingValue<Long> shardingValue) {

Collection<String> 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<String> doBetweenSharding(Collection<String> databaseNames, ShardingValue<Long> shardingValue) {

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

Range<Long> range = (Range<Long>) 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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50
import java.util.Collection;

import java.util.LinkedHashSet;

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

import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;

import com.google.common.collect.Range;

/**

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

*/

public class ModuloTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Long> {

@Override

public String doEqualSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) {

for (String each : tableNames) {

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

return each;

}

}

throw new IllegalArgumentException();

}

@Override

public Collection<String> doInSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) {

Collection<String> 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<String> doBetweenSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) {

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

Range<Long> range = (Range<Long>) 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之前加一层主从数据源的创建

?

1

2

3

4

5

6

7

8

9

10

11

12

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

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

DataSource masterSlaveDs0 = MasterSlaveDataSourceFactory.createDataSource("ms_0",

masterDataSource0, slaveDataSource00, slaveDataSource01);

DataSource masterSlaveDs1 = MasterSlaveDataSourceFactory.createDataSource("ms_1",

masterDataSource1, slaveDataSource11, slaveDataSource11);

// 构建分库分表数据源

Map<String, DataSource> dataSourceMap = new HashMap<>(2);

dataSourceMap.put("ms_0", masterSlaveDs0);

dataSourceMap.put("ms_1", masterSlaveDs1);

// 通过ShardingDataSourceFactory继续创建ShardingDataSource

强制使用主库时

?

1

2

3
HintManager hintManager = HintManager.getInstance();

hintManager.setMasterRouteOnly();

// 继续JDBC操作

强制路由

  1. 使用ThreadLocal机制实现,在执行数据库操作之前通过HintManager改变用于计算路由的值
  2. 设置HintManager的时候分库和分表的策略必须同时设置,并且设置后需要路由的表都需要设置用于计算路由的值。比如强制路由后需要操作t_order和t_order_item两个表,那么两个表的分库和分表的策略都需要设置
?

1

2

3

4

5
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());

事务

  1. sharding-jdbc-transaction实现柔性事务(默认提供了基于内存的事务日志存储器和内嵌异步作业),可结合elastic-job(sharding-jdbc-transaction-async-job)实现异步柔性事务
  2. 没有与spring结合使用的方式,需要自己封装

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

原文链接:https://my.oschina.net/dengfuwei/blog/1595151

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 spring boot使用sharding jdbc的配置方式 https://www.kuaiidc.com/113318.html

相关文章

发表评论
暂无评论