利用Sharding-Jdbc实现分表(亲测成功)

利用Sharding-Jdbc实现分表
闲来无事,喜欢研究一些自己未接触过的技术~

看到了当当开源的Sharding-JDBC组件,它可以在几乎不修改代码的情况下完成分库分表的实现。摘抄其中一段介绍:

  Sharding-JDBC直接封装JDBC API,可以理解为增强版的JDBC驱动,旧代码迁移成本几乎为零:

可适用于任何基于java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。

可基于任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid等。

理论上可支持任意实现JDBC规范的数据库。虽然目前仅支持MySQL,但已有支持Oracle,SQLServer,DB2等数据库的计划。

先做一个最简单的试用,不做分库,仅做分表。选择数据表bead_information,首先复制成三个表:bead_information_0、bead_information_1、bead_information_2

测试实现过程
前提:已经实现srping+mybatis对单库单表做增删改查的项目。

1、修改pom.xml增加dependency

    
        com.dangdang
        sharding-jdbc-core
        1.4.2
    
    
        com.dangdang
        sharding-jdbc-config-spring
        1.4.0
        

2、新建一个sharding-jdbc.xml文件,实现分库分表的配置

    

    



 

    
    
    

             



    
        
            
        
    



    

jndi 形式




	
		
			
		
	

标记

3、将文件引入spring配置文件中。

  需要修改几个地方,把sqlSessionFactory和transactionManager原来关联的dataSource统一修改为shardingDataSource(这一步作用就是把数据源全部托管给sharding去管理)

4、实现分表(分库)逻辑,我们的分表逻辑类需要实现SingleKeyTableShardingAlgorithm接口的三个方法doBetweenSharding、doEqualSharding、doInSharding

(取模除数需要按照自己需求改变,我这里分3个表,所以除以3)

复制代码(分表策略实测)

package com.suning.jupiter.common.utils;

import java.util.Collection;
import java.util.LinkedHashSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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 MemberSingleKeyTableShardingAlgorithm  implements SingleKeyTableShardingAlgorithm{
public static final Logger logger = LoggerFactory.getLogger(MemberSingleKeyTableShardingAlgorithm.class);

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

public String doEqualSharding(Collection tableNames, ShardingValue shardingValue) {
	Number value = (Number)shardingValue.getValue();
	logger.info("shardingValue.getValue()::::{}",value.getClass().getName());
	Long modValue = value.longValue() % 4;
	String modStr = modValue < 4 ? "" + modValue : modValue.toString();
	for (String each : tableNames) {
		if (each.endsWith(modStr)) {
			return each;
		}
	}
	throw new IllegalArgumentException();
}

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

5、配置完成,可以实现增删改查测试。

这里我简单介绍下一些属性的含义

配置分表规则器
sharding-columns:分表规 则依赖的名(根据user_id取模分表),
algorithm-class:分表规则的实现类 ,
这里填写关联数据源(多个数据源用逗号隔开),

[ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] {[0,1,2,3,4,5,6,7,8,9]} [0,1,2,3,4,5,6,7,8,9]{0…9}” table-strategy=“tableShardingStrategy”/>
logic-table:逻辑表名(mybatis中代替的表名)
actual-tables:数据库实际的表名,这里支持inline表达式,比如:member_index_tbl_KaTeX parse error: Expected group after '_' at position 84: …ember_index_tbl_̲{[a,b,c]}会被解析成member_index_tbl_a,member_index_tbl_b和member_index_tbl_c,两种表达式一起使用的时候,会采取笛卡尔积的方式:member_index_tbl_ [ a , b ] {[a,b]} [a,b]{0…2}解析为member_index_tbl_a0,member_index_tbl_a1 member_index_tbl_a2,member_index_tbl_b0,member_index_tbl_b1,member_index_tbl_b2;
table-strategy:前面定义的分表规则器;

你可能感兴趣的:(java开发)