当前位置: 移动技术网 > IT编程>开发语言>Java > spring boot使用sharding jdbc的配置方式

spring boot使用sharding jdbc的配置方式

2019年07月19日  | 移动技术网IT编程  | 我要评论

本文介绍了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操作

强制路由

  1. 使用threadlocal机制实现,在执行数据库操作之前通过hintmanager改变用于计算路由的值
  2. 设置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());

事务

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

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网