diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/strategy/ShardingStrategy.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/strategy/ShardingStrategy.java index 9cd3b260cea3973544450041376feda02f186bf8..29ba520da92bc95b07d12c058080110672c4b0c9 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/strategy/ShardingStrategy.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/strategy/ShardingStrategy.java @@ -20,12 +20,10 @@ package com.dangdang.ddframe.rdb.sharding.routing.strategy; import com.dangdang.ddframe.rdb.sharding.api.ShardingValue; import com.dangdang.ddframe.rdb.sharding.routing.strategy.complex.ComplexKeysShardingAlgorithm; import com.dangdang.ddframe.rdb.sharding.routing.strategy.hint.HintShardingAlgorithm; -import com.google.common.base.Preconditions; import lombok.Getter; import lombok.NoArgsConstructor; import java.util.Collection; -import java.util.Collections; import java.util.TreeSet; /** @@ -54,38 +52,17 @@ public class ShardingStrategy { * @param shardingValues sharding values * @return sharding results for data sources or tables's names */ - public Collection doStaticSharding(final Collection availableTargetNames, final Collection shardingValues) { - Collection result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - if (shardingValues.isEmpty()) { - result.addAll(availableTargetNames); + public Collection doSharding(final Collection availableTargetNames, final Collection shardingValues) { + Collection shardingResult; + if (shardingAlgorithm instanceof HintShardingAlgorithm) { + shardingResult = ((HintShardingAlgorithm) shardingAlgorithm).doSharding(availableTargetNames, shardingValues.iterator().next()); + } else if (shardingAlgorithm instanceof ComplexKeysShardingAlgorithm) { + shardingResult = ((ComplexKeysShardingAlgorithm) shardingAlgorithm).doSharding(availableTargetNames, shardingValues); } else { - result.addAll(doSharding(shardingValues, availableTargetNames)); + throw new UnsupportedOperationException(shardingAlgorithm.getClass().getName()); } - return result; - } - - /** - * Calculate dynamic sharding info. - * - * @param shardingValues sharding values - * @return sharding results for data sources or tables's names - */ - public Collection doDynamicSharding(final Collection shardingValues) { - Preconditions.checkState(!shardingValues.isEmpty(), "Dynamic table should contain sharding value."); - Collection availableTargetNames = Collections.emptyList(); Collection result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - result.addAll(doSharding(shardingValues, availableTargetNames)); + result.addAll(shardingResult); return result; } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private Collection doSharding(final Collection shardingValues, final Collection availableTargetNames) { - if (shardingAlgorithm instanceof HintShardingAlgorithm) { - return ((HintShardingAlgorithm) shardingAlgorithm).doSharding(availableTargetNames, shardingValues.iterator().next()); - } - if (shardingAlgorithm instanceof ComplexKeysShardingAlgorithm) { - return ((ComplexKeysShardingAlgorithm) shardingAlgorithm).doSharding(availableTargetNames, shardingValues); - } - throw new UnsupportedOperationException(shardingAlgorithm.getClass().getName()); - } } diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/strategy/standard/StandardShardingStrategy.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/strategy/standard/StandardShardingStrategy.java index a0878d0998f3273d09cb220caa7731603678a8e5..3e74c8923d7522fcd31593599daddd54084f9de9 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/strategy/standard/StandardShardingStrategy.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/strategy/standard/StandardShardingStrategy.java @@ -17,13 +17,18 @@ package com.dangdang.ddframe.rdb.sharding.routing.strategy.standard; +import com.dangdang.ddframe.rdb.sharding.api.ListShardingValue; import com.dangdang.ddframe.rdb.sharding.api.PreciseShardingValue; import com.dangdang.ddframe.rdb.sharding.api.RangeShardingValue; +import com.dangdang.ddframe.rdb.sharding.api.ShardingValue; import com.dangdang.ddframe.rdb.sharding.routing.strategy.ShardingStrategy; import com.google.common.base.Optional; import lombok.Getter; +import java.util.ArrayList; import java.util.Collection; +import java.util.LinkedList; +import java.util.List; import java.util.TreeSet; /** @@ -50,33 +55,40 @@ public final class StandardShardingStrategy extends ShardingStrategy { this.rangeShardingAlgorithm = Optional.fromNullable(rangeShardingAlgorithm); } - /** - * Calculate precise sharding info. - * - * @param availableTargetNames available data sources or tables's names - * @param shardingValue sharding value - * @return sharding results for data sources or tables's names - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public String doPreciseSharding(final Collection availableTargetNames, final PreciseShardingValue shardingValue) { - return preciseShardingAlgorithm.doSharding(availableTargetNames, shardingValue); + public Collection doSharding(final Collection availableTargetNames, final ShardingValue shardingValue) { + Collection shardingResult = shardingValue instanceof ListShardingValue + ? doSharding(availableTargetNames, (ListShardingValue) shardingValue) : doSharding(availableTargetNames, (RangeShardingValue) shardingValue); + Collection result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + result.addAll(shardingResult); + return result; } - /** - * Calculate range sharding info. - * - * @param availableTargetNames available data sources or tables's names - * @param shardingValue sharding value - * @return sharding results for data sources or tables's names - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Collection doRangeSharding(final Collection availableTargetNames, final RangeShardingValue shardingValue) { + @SuppressWarnings("unchecked") + private Collection doSharding(final Collection availableTargetNames, final RangeShardingValue shardingValue) { if (!rangeShardingAlgorithm.isPresent()) { throw new UnsupportedOperationException("Cannot find range sharding strategy in sharding rule."); } return rangeShardingAlgorithm.get().doSharding(availableTargetNames, shardingValue); } + @SuppressWarnings("unchecked") + private Collection doSharding(final Collection availableTargetNames, final ListShardingValue shardingValue) { + Collection result = new LinkedList<>(); + for (PreciseShardingValue eachTableShardingValue : transferToPreciseShardingValues(shardingValue)) { + result.add(preciseShardingAlgorithm.doSharding(availableTargetNames, eachTableShardingValue)); + } + return result; + } + + @SuppressWarnings("unchecked") + private List transferToPreciseShardingValues(final ListShardingValue shardingValue) { + List result = new ArrayList<>(shardingValue.getValues().size()); + for (Comparable each : shardingValue.getValues()) { + result.add(new PreciseShardingValue(shardingValue.getLogicTableName(), shardingValue.getColumnName(), each)); + } + return result; + } + @Override public Collection getShardingColumns() { Collection result = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/type/hint/DatabaseHintRoutingEngine.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/type/hint/DatabaseHintRoutingEngine.java index 182549590e6c29415c218c2d73b4090282448bf1..6f4c221976fece37e6d2993600509cff85ef2705 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/type/hint/DatabaseHintRoutingEngine.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/type/hint/DatabaseHintRoutingEngine.java @@ -53,7 +53,7 @@ public final class DatabaseHintRoutingEngine implements RoutingEngine { Preconditions.checkState(shardingValue.isPresent()); log.debug("Before database sharding only db:{} sharding values: {}", dataSourceRule.getDataSourceNames(), shardingValue.get()); Collection routingDataSources; - routingDataSources = databaseShardingStrategy.doStaticSharding(dataSourceRule.getDataSourceNames(), Collections.singleton(shardingValue.get())); + routingDataSources = databaseShardingStrategy.doSharding(dataSourceRule.getDataSourceNames(), Collections.singleton(shardingValue.get())); Preconditions.checkState(!routingDataSources.isEmpty(), "no database route info"); log.debug("After database sharding only result: {}", routingDataSources); RoutingResult result = new RoutingResult(); diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/type/simple/SimpleRoutingEngine.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/type/simple/SimpleRoutingEngine.java index 1cca74a5032db3b6cd05c71a1241a1e693abfa33..79d96728423584d3fef18549fef9deedad1fc5f5 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/type/simple/SimpleRoutingEngine.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/routing/type/simple/SimpleRoutingEngine.java @@ -17,9 +17,6 @@ package com.dangdang.ddframe.rdb.sharding.routing.type.simple; -import com.dangdang.ddframe.rdb.sharding.api.ListShardingValue; -import com.dangdang.ddframe.rdb.sharding.api.PreciseShardingValue; -import com.dangdang.ddframe.rdb.sharding.api.RangeShardingValue; import com.dangdang.ddframe.rdb.sharding.api.ShardingValue; import com.dangdang.ddframe.rdb.sharding.api.rule.DataNode; import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule; @@ -42,7 +39,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -120,53 +116,33 @@ public final class SimpleRoutingEngine implements RoutingEngine { } private Collection routeDataSources(final TableRule tableRule, final List databaseShardingValues) { + Collection availableTargetDatabases = tableRule.getActualDatasourceNames(); + if (databaseShardingValues.isEmpty()) { + return availableTargetDatabases; + } ShardingStrategy strategy = shardingRule.getDatabaseShardingStrategy(tableRule); - if (strategy instanceof StandardShardingStrategy && !databaseShardingValues.isEmpty()) { - if (isPreciseSharding(databaseShardingValues)) { - Collection result = new LinkedList<>(); - Collection preciseDatabaseShardingValues = transferToShardingValues((ListShardingValue) databaseShardingValues.get(0)); - for (PreciseShardingValue eachDatabaseShardingValue : preciseDatabaseShardingValues) { - result.add(((StandardShardingStrategy) strategy).doPreciseSharding(tableRule.getActualDatasourceNames(), eachDatabaseShardingValue)); - } - return result; - } - return ((StandardShardingStrategy) strategy).doRangeSharding(tableRule.getActualDatasourceNames(), (RangeShardingValue) databaseShardingValues.get(0)); + if (strategy instanceof StandardShardingStrategy) { + return ((StandardShardingStrategy) strategy).doSharding(availableTargetDatabases, databaseShardingValues.get(0)); } - Collection result = shardingRule.getDatabaseShardingStrategy(tableRule).doStaticSharding(tableRule.getActualDatasourceNames(), databaseShardingValues); + Collection result = strategy.doSharding(tableRule.getActualDatasourceNames(), databaseShardingValues); Preconditions.checkState(!result.isEmpty(), "no database route info"); return result; } private Collection routeTables(final TableRule tableRule, final String routedDataSource, final List tableShardingValues) { - ShardingStrategy strategy = shardingRule.getTableShardingStrategy(tableRule); + if (tableShardingValues.isEmpty() && tableRule.isDynamic()) { + throw new UnsupportedOperationException("Dynamic table should contain sharding value."); + } Collection availableTargetTables = tableRule.isDynamic() ? Collections.emptyList() : tableRule.getActualTableNames(routedDataSource); - if (strategy instanceof StandardShardingStrategy && !tableShardingValues.isEmpty()) { - if (isPreciseSharding(tableShardingValues)) { - Collection result = new LinkedList<>(); - Collection preciseTableShardingValues = transferToShardingValues((ListShardingValue) tableShardingValues.get(0)); - for (PreciseShardingValue eachTableShardingValue : preciseTableShardingValues) { - result.add(((StandardShardingStrategy) strategy).doPreciseSharding(availableTargetTables, eachTableShardingValue)); - } - return result; - } - return ((StandardShardingStrategy) strategy).doRangeSharding(availableTargetTables, (RangeShardingValue) tableShardingValues.get(0)); + if (tableShardingValues.isEmpty()) { + return availableTargetTables; } - Collection result = - tableRule.isDynamic() ? strategy.doDynamicSharding(tableShardingValues) : strategy.doStaticSharding(tableRule.getActualTableNames(routedDataSource), tableShardingValues); - Preconditions.checkState(!result.isEmpty(), "no table route info"); - return result; - } - - private boolean isPreciseSharding(final List shardingValues) { - return 1 == shardingValues.size() && !(shardingValues.get(0) instanceof RangeShardingValue); - } - - @SuppressWarnings("unchecked") - private List transferToShardingValues(final ListShardingValue shardingValue) { - List result = new ArrayList<>(shardingValue.getValues().size()); - for (Comparable each : shardingValue.getValues()) { - result.add(new PreciseShardingValue(shardingValue.getLogicTableName(), shardingValue.getColumnName(), each)); + ShardingStrategy strategy = shardingRule.getTableShardingStrategy(tableRule); + if (strategy instanceof StandardShardingStrategy) { + return ((StandardShardingStrategy) strategy).doSharding(availableTargetTables, tableShardingValues.get(0)); } + Collection result = strategy.doSharding(availableTargetTables, tableShardingValues); + Preconditions.checkState(!result.isEmpty(), "no table route info"); return result; } diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingStrategyTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingStrategyTest.java index d52013c100e8cf50881d76ba42f4ca6474f51b71..2adce559985b4e7dd1681d979be5a652ab342aaf 100644 --- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingStrategyTest.java +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingStrategyTest.java @@ -26,7 +26,6 @@ import com.dangdang.ddframe.rdb.sharding.api.strategy.fixture.TestRangeShardingA import com.dangdang.ddframe.rdb.sharding.api.strategy.sharding.NoneShardingAlgorithm; import com.dangdang.ddframe.rdb.sharding.routing.strategy.ShardingStrategy; import com.dangdang.ddframe.rdb.sharding.routing.strategy.standard.StandardShardingStrategy; -import com.google.common.collect.Lists; import com.google.common.collect.Range; import com.google.common.collect.Sets; import org.junit.Test; @@ -44,40 +43,27 @@ public final class ShardingStrategyTest { @Test public void assertDoStaticShardingWithoutShardingColumns() { ShardingStrategy strategy = new ShardingStrategy(Sets.newHashSet("column"), new NoneShardingAlgorithm()); - assertThat(strategy.doStaticSharding(targets, Collections.emptySet()), is(targets)); + assertThat(strategy.doSharding(targets, Collections.emptySet()), is(targets)); } @Test public void assertDoStaticShardingForBetweenSingleKey() { StandardShardingStrategy strategy = new StandardShardingStrategy("column", new TestPreciseShardingAlgorithm(), new TestRangeShardingAlgorithm()); - assertThat(strategy.doRangeSharding(targets, new RangeShardingValue<>("logicTable", "column", Range.open("1", "3"))), - is((Collection) Lists.newArrayList("1", "2", "3"))); + assertThat(strategy.doSharding(targets, new RangeShardingValue<>("logicTable", "column", Range.open("1", "3"))), + is((Collection) Sets.newHashSet("1", "2", "3"))); } @Test public void assertDoStaticShardingForMultipleKeys() { ShardingStrategy strategy = new ShardingStrategy(Collections.singletonList("column"), new TestComplexKeysShardingAlgorithm()); - assertThat(strategy.doStaticSharding(targets, Collections.singletonList(new PreciseShardingValue<>("logicTable", "column", "1"))), + assertThat(strategy.doSharding(targets, Collections.singletonList(new PreciseShardingValue<>("logicTable", "column", "1"))), is((Collection) Sets.newHashSet("1", "2", "3"))); } - @Test(expected = IllegalStateException.class) - public void assertDoDynamicShardingWithoutShardingColumns() { - ShardingStrategy strategy = new ShardingStrategy(Sets.newHashSet("column"), null); - strategy.doDynamicSharding(Collections.emptySet()); - } - @Test public void assertDoDynamicShardingForBetweenSingleKey() { StandardShardingStrategy strategy = new StandardShardingStrategy("column", new TestPreciseShardingAlgorithm(), new TestRangeShardingAlgorithm()); - assertThat(strategy.doRangeSharding(Collections.emptyList(), new RangeShardingValue<>("logicTable", "column", Range.open("1", "3"))), - is((Collection) Lists.newArrayList("1", "2", "3"))); - } - - @Test - public void assertDoDynamicShardingForMultipleKeys() { - ShardingStrategy strategy = new ShardingStrategy(Collections.singletonList("column"), new TestComplexKeysShardingAlgorithm()); - assertThat(strategy.doDynamicSharding(Collections.singletonList(new PreciseShardingValue<>("logicTable", "column", "1"))), - is((Collection) Collections.emptySet())); + assertThat(strategy.doSharding(Collections.emptyList(), new RangeShardingValue<>("logicTable", "column", Range.open("1", "3"))), + is((Collection) Sets.newHashSet("1", "2", "3"))); } }