Spring Boot中整合Sharding-JDBC單庫分表示例

本文是Sharding-JDBC採用Spring Boot Starter方式配置第二篇,第一篇是讀寫分離講解,請參考:《Spring Boot中整合Sharding-JDBC讀寫分離示例》java

在我《Spring Cloud微服務-全棧技術與案例解析》書中都是經過XML方式配置。今天給你們演示的是單庫中分表的操做,若是用XML方式配置,那麼就是下面的配置:node

<!-- 數據源 -->
    <bean id="ds_0" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" primary="true">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8" />
        <property name="username" value="root" />
        <property name="password" value="123456" />
    </bean>
    

    <!-- algorithm-class="com.fangjia.sharding.UserSingleKeyTableShardingAlgorithm" -->
    <!-- user_0,user_1,user_2,user_3 -->
    <rdb:strategy id="userTableStrategy" sharding-columns="id" algorithm-expression="user_${id.longValue() % 4}"/>
    <rdb:data-source id="dataSource">
        <rdb:sharding-rule data-sources="ds_0">
            <rdb:table-rules>
                <rdb:table-rule logic-table="user" actual-tables="user_${0..3}" table-strategy="userTableStrategy"/>
            </rdb:table-rules>
            <rdb:default-database-strategy sharding-columns="none" algorithm-class="com.dangdang.ddframe.rdb.sharding.api.strategy.database.NoneDatabaseShardingAlgorithm"/>
        </rdb:sharding-rule>
    </rdb:data-source>

咱們將user表分紅了4個,分別是user_0,user_1,user_2,user_3,經過id取模的方式決定數據落在哪張表上面。mysql

若是用Spring Boot方式配置天然就簡單多了,以下:git

sharding.jdbc.datasource.names=ds_master
# 數據源
sharding.jdbc.datasource.ds_master.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.ds_master.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.ds_master.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8
sharding.jdbc.datasource.ds_master.username=root
sharding.jdbc.datasource.ds_master.password=123456
# 分表配置
sharding.jdbc.config.sharding.tables.user.actual-data-nodes=ds_master.user_${0..3}
sharding.jdbc.config.sharding.tables.user.table-strategy.inline.sharding-column=id
sharding.jdbc.config.sharding.tables.user.table-strategy.inline.algorithm-expression=user_${id.longValue() % 4}
  • actual-data-nodes:真實數據節點,由數據源名 + 表名組成,以小數點分隔。多個表以逗號分隔,支持inline表達式。
  • table-strategy.inline.sharding-column:分片字段配置
  • table-strategy.inline.algorithm-expression:分片算法表達式

自定義分片算法

在1.x版本中,單分片算法是經過實現SingleKeyTableShardingAlgorithm,示例代碼以下:github

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;

public class UserSingleKeyTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Long>  {

    public String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Long> shardingValue) {
        for (String each : availableTargetNames) {
            System.out.println(each+"\t"+shardingValue.getValue()+"\t"+shardingValue.getValue() % 4 );
            if (each.endsWith(shardingValue.getValue() % 4 + "")) {
                return each;
            }
        }
        throw new IllegalArgumentException();
    }

    public Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Long> shardingValue) {
         Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
            for (Long value : shardingValue.getValues()) {
                for (String tableName : availableTargetNames) {
                    if (tableName.endsWith(value % 4 + "")) {
                        result.add(tableName);
                    }
                }
            }
            return result;
    }

    public Collection<String> doBetweenSharding(Collection<String> availableTargetNames,
            ShardingValue<Long> shardingValue) {
        Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
        Range<Long> range = (Range<Long>) shardingValue.getValueRange();
        for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
            for (String each : availableTargetNames) {
                if (each.endsWith(i % 4 + "")) {
                    result.add(each);
                }
            }
        }
        return result;
    }

}

咱們這邊引入的Spring Boot Starter包是2.x的版本,在這個版本中,分片算法的接口有調整,咱們須要用到標準分片策略StandardShardingStrategy。提供對SQL語句中的=, IN和BETWEEN AND的分片操做支持。StandardShardingStrategy只支持單分片鍵,提供PreciseShardingAlgorithm和RangeShardingAlgorithm兩個分片算法。PreciseShardingAlgorithm是必選的,用於處理=和IN的分片。RangeShardingAlgorithm是可選的,用於處理BETWEEN AND分片,若是不配置RangeShardingAlgorithm,SQL中的BETWEEN AND將按照全庫路由處理。算法

自定義一個單分片算法spring

import java.util.Collection;
import io.shardingjdbc.core.api.algorithm.sharding.PreciseShardingValue;
import io.shardingjdbc.core.api.algorithm.sharding.standard.PreciseShardingAlgorithm;
/**
 * 自定義分片算法
 * 
 * @author yinjihuan
 *
 */
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
        for (String tableName : availableTargetNames) {
            if (tableName.endsWith(shardingValue.getValue() % 4 + "")) {
                return tableName;
            }
        }
        throw new IllegalArgumentException();
    }

}

使用須要修改咱們以前的配置sql

sharding.jdbc.config.sharding.tables.user.actual-data-nodes=ds_master.user_${0..3}
sharding.jdbc.config.sharding.tables.user.table-strategy.standard.sharding-column=id
sharding.jdbc.config.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name=com.fangjia.sharding.MyPreciseShardingAlgorithm

源碼參考:
https://github.com/yinjihuan/...數據庫

參考代碼中測試的代碼也寫好了,在Controller中,啓動後經過調用接口的方式測試數據的添加和查詢。express

另外Sharding-Sphere 3.0.0.M3也發佈了,新版本看點:
1.XA分佈式事務
2.數據庫治理模塊加強
3.API部分調整
4.修復M2Bug

項目地址:
https://github.com/sharding-s...
https://gitee.com/sharding-sp...

一個這麼優秀的框架,這麼靠譜的研發團隊,你們趕忙學起來呀!

歡迎加入個人知識星球,一塊兒交流技術,免費學習猿天地的課程(http://cxytiandi.com/course

微信掃碼加入猿天地知識星球

猿天地

相關文章
相關標籤/搜索