spring boot使用sharding jdbc的配置方式
程序员文章站
2023-12-21 08:13:40
本文介绍了spring boot使用sharding jdbc的配置方式,分享给大家,具体如下:
说明
要排除datasourceautoconfiguration,否...
本文介绍了spring boot使用sharding jdbc的配置方式,分享给大家,具体如下:
说明
要排除datasourceautoconfiguration,否则多数据源无法配置
@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使用
官方文档:
步骤
配置多个数据源,数据源的名称最好要有一定的规则,方便配置分库的计算规则
@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<string, datasource> 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<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会使用此数据源
@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<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
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之前加一层主从数据源的创建
// 构建读写分离数据源, 读写分离数据源实现了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
强制使用主库时
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结合使用的方式,需要自己封装
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
spring boot使用sharding jdbc的配置方式
-
Spring Boot 配置和使用多线程池的实现
-
基于Spring Boot不同的环境使用不同的配置方法
-
SpringBoot入坑笔记之spring-boot-starter-web 配置文件的使用
-
Spring Boot 配置和使用多线程池的实现
-
spring boot使用sharding jdbc的配置方式
-
Spring Boot使用profile如何配置不同环境的配置文件
-
spring boot使用自定义配置的线程池执行Async异步任务
-
详解Spring Boot下Druid连接池的使用配置分析
-
SpringBoot入坑笔记之spring-boot-starter-web 配置文件的使用