zoukankan      html  css  js  c++  java
  • Spring Boot中整合Sharding-JDBC单库分表示例

    本文是Sharding-JDBC采用Spring Boot Starter方式配置第二篇,第一篇是读写分离讲解,请参考:《Spring Boot中整合Sharding-JDBC读写分离示例》

    在我《Spring Cloud微服务-全栈技术与案例解析》书中都是通过XML方式配置。今天给大家演示的是单库中分表的操作,如果用XML方式配置,那么就是下面的配置:

      <!-- 数据源 -->
        <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取模的方式决定数据落在哪张表上面。

    如果用Spring Boot方式配置自然就简单多了,如下:

    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,示例代码如下:

    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+"	"+shardingValue.getValue()+"	"+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将按照全库路由处理。

    自定义一个单分片算法

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

    使用需要修改我们之前的配置

    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/spring-cloud/tree/master/fangjia-sjdbc-sharding-table-springboot

    参考代码中测试的代码也写好了,在Controller中,启动后通过调用接口的方式测试数据的添加和查询。

    另外Sharding-Sphere 3.0.0.M3也发布了,新版本看点:
    1.XA分布式事务
    2.数据库治理模块增强
    3.API部分调整
    4.修复M2Bug

    项目地址:
    https://github.com/sharding-sphere/sharding-sphere/
    https://gitee.com/sharding-sphere/sharding-sphere/

    一个这么优秀的框架,这么靠谱的研发团队,大家赶紧学起来呀!

    欢迎加入我的知识星球,一起交流技术,免费学习猿天地的课程(http://cxytiandi.com/course)

    微信扫码加入猿天地知识星球

    猿天地

  • 相关阅读:
    HDU 5937 Equation
    HDU 5936 Difference
    hdu 4348 To the moon
    SPOJ QTREE Query on a tree
    HDU 3966 Aragorn's Story
    Codeforces 733F Drivers Dissatisfaction
    道良心题
    dp小总结
    数据结构
    数学相关(偏数学向题目的集中地)
  • 原文地址:https://www.cnblogs.com/yinjihuan/p/10481342.html
Copyright © 2011-2022 走看看