From bba72169f970454a0c16bffa516f23890a6c966c Mon Sep 17 00:00:00 2001
From: terrymanu
Date: Mon, 18 Jan 2016 21:33:03 +0800
Subject: [PATCH 1/7] init version
---
.gitignore | 38 +-
README.md | 91 +
pom.xml | 650 ++
sharding-jdbc-core/pom.xml | 82 +
.../rdb/sharding/api/DatabaseType.java | 44 +
.../rdb/sharding/api/ShardingDataSource.java | 94 +
.../rdb/sharding/api/ShardingValue.java | 88 +
.../api/config/ShardingConfiguration.java | 74 +
.../config/ShardingConfigurationConstant.java | 53 +
.../sharding/api/rule/BindingTableRule.java | 90 +
.../rdb/sharding/api/rule/DataNode.java | 39 +
.../rdb/sharding/api/rule/DataSourceRule.java | 69 +
.../rdb/sharding/api/rule/ShardingRule.java | 213 +
.../rdb/sharding/api/rule/TableRule.java | 134 +
.../common/MultipleKeysShardingAlgorithm.java | 39 +
.../strategy/common/ShardingAlgorithm.java | 26 +
.../api/strategy/common/ShardingStrategy.java | 76 +
.../common/SingleKeyShardingAlgorithm.java | 59 +
.../database/DatabaseShardingAlgorithm.java | 28 +
.../database/DatabaseShardingStrategy.java | 38 +
...MultipleKeysDatabaseShardingAlgorithm.java | 28 +
.../NoneDatabaseShardingAlgorithm.java | 50 +
.../SingleKeyDatabaseShardingAlgorithm.java | 28 +
.../MultipleKeysTableShardingAlgorithm.java | 28 +
.../table/NoneTableShardingAlgorithm.java | 50 +
.../SingleKeyTableShardingAlgorithm.java | 28 +
.../table/TableShardingAlgorithm.java | 28 +
.../strategy/table/TableShardingStrategy.java | 38 +
.../DatabaseTypeUnsupportedException.java | 34 +
.../exception/SQLParserException.java | 32 +
.../exception/ShardingJdbcException.java | 36 +
.../rdb/sharding/executor/ExecuteUnit.java | 35 +
.../rdb/sharding/executor/ExecutorEngine.java | 116 +
.../rdb/sharding/executor/MergeUnit.java | 36 +
.../executor/PreparedStatementExecutor.java | 125 +
.../sharding/executor/StatementExecutor.java | 237 +
.../jdbc/AbstractShardingResultSet.java | 77 +
.../rdb/sharding/jdbc/ShardingConnection.java | 129 +
.../jdbc/ShardingPreparedStatement.java | 186 +
.../rdb/sharding/jdbc/ShardingStatement.java | 194 +
.../adapter/AbstractConnectionAdapter.java | 142 +
.../adapter/AbstractDataSourceAdapter.java | 53 +
.../AbstractPreparedStatementAdapter.java | 275 +
.../adapter/AbstractResultSetAdapter.java | 119 +
.../AbstractResultSetGetterAdapter.java | 327 +
.../adapter/AbstractStatementAdapter.java | 163 +
.../sharding/jdbc/adapter/WrapperAdapter.java | 77 +
.../AbstractResultSetUpdaterAdapter.java | 455 ++
...bstractUnsupportedOperationConnection.java | 184 +
...bstractUnsupportedOperationDataSource.java | 43 +
...UnsupportedOperationPreparedStatement.java | 95 +
...AbstractUnsupportedOperationResultSet.java | 224 +
...AbstractUnsupportedOperationStatement.java | 103 +
.../jdbc/util/JdbcMethodInvocation.java | 51 +
.../rdb/sharding/merger/ResultSetFactory.java | 75 +
.../aggregation/AbstractAggregationUnit.java | 48 +
.../AccumulationAggregationUnit.java | 50 +
.../aggregation/AggregationInvokeHandler.java | 69 +
.../aggregation/AggregationResultSet.java | 68 +
.../merger/aggregation/AggregationUnit.java | 48 +
.../aggregation/AggregationUnitFactory.java | 49 +
.../merger/aggregation/AggregationValue.java | 38 +
.../aggregation/AvgAggregationUnit.java | 54 +
.../ComparableAggregationUnit.java | 55 +
.../ResultSetAggregationValue.java | 37 +
.../common/AbstractMergerInvokeHandler.java | 58 +
.../merger/common/ResultSetQueryIndex.java | 71 +
.../sharding/merger/common/ResultSetUtil.java | 155 +
.../merger/groupby/GroupByInvokeHandler.java | 43 +
.../sharding/merger/groupby/GroupByKey.java | 40 +
.../merger/groupby/GroupByResultSet.java | 194 +
.../sharding/merger/groupby/GroupByValue.java | 114 +
.../merger/iterator/IteratorResultSet.java | 52 +
.../merger/orderby/OrderByResultSet.java | 81 +
.../sharding/merger/orderby/OrderByValue.java | 81 +
.../rdb/sharding/metrics/MetricsContext.java | 87 +
.../rdb/sharding/parser/SQLParseEngine.java | 73 +
.../rdb/sharding/parser/SQLParserFactory.java | 99 +
.../sharding/parser/SQLVisitorRegistry.java | 127 +
.../parser/result/SQLParsedResult.java | 44 +
.../result/merger/AggregationColumn.java | 63 +
.../parser/result/merger/GroupByColumn.java | 41 +
.../sharding/parser/result/merger/Limit.java | 37 +
.../parser/result/merger/MergeContext.java | 71 +
.../parser/result/merger/OrderByColumn.java | 71 +
.../parser/result/router/Condition.java | 79 +
.../result/router/ConditionContext.java | 88 +
.../parser/result/router/RouteContext.java | 40 +
.../parser/result/router/SQLBuilder.java | 150 +
.../sharding/parser/result/router/Table.java | 45 +
.../sharding/parser/visitor/ParseContext.java | 312 +
.../sharding/parser/visitor/SQLVisitor.java | 57 +
.../parser/visitor/VisitorLogProxy.java | 103 +
.../basic/mysql/AbstractMySQLVisitor.java | 165 +
.../basic/mysql/MySQLDeleteVisitor.java | 35 +
.../basic/mysql/MySQLInsertVisitor.java | 39 +
.../basic/mysql/MySQLSelectVisitor.java | 195 +
.../basic/mysql/MySQLUpdateVisitor.java | 35 +
.../sharding/parser/visitor/or/OrParser.java | 55 +
.../sharding/parser/visitor/or/OrVisitor.java | 98 +
.../visitor/or/node/AbstractOrASTNode.java | 107 +
.../visitor/or/node/CompositeOrASTNode.java | 52 +
.../visitor/or/node/SimpleOrASTNode.java | 72 +
.../rdb/sharding/router/RoutingResult.java | 38 +
.../rdb/sharding/router/SQLExecutionUnit.java | 43 +
.../rdb/sharding/router/SQLRouteEngine.java | 103 +
.../rdb/sharding/router/SQLRouteResult.java | 40 +
.../binding/BindingRoutingDataSource.java | 55 +
.../router/binding/BindingRoutingResult.java | 51 +
.../binding/BindingRoutingTableFactor.java | 52 +
.../router/binding/BindingTablesRouter.java | 73 +
.../router/mixed/CartesianDataSource.java | 57 +
.../router/mixed/CartesianResult.java | 66 +
.../router/mixed/CartesianTableReference.java | 49 +
.../router/mixed/CartesianTablesRouter.java | 126 +
.../router/mixed/MixedTablesRouter.java | 77 +
.../single/SingleRoutingDataSource.java | 107 +
.../router/single/SingleRoutingResult.java | 149 +
.../single/SingleRoutingTableFactor.java | 48 +
.../router/single/SingleTableRouter.java | 140 +
.../com/dangdang/ddframe/rdb/AllTests.java | 43 +
.../rdb/integrate/AbstractDBUnitTest.java | 146 +
.../rdb/integrate/AllIntegrateTests.java | 70 +
.../rdb/integrate/DataBaseEnvironment.java | 71 +
.../integrate/ShardingJdbcDatabaseTester.java | 46 +
...stractShardingDataBasesOnlyDBUnitTest.java | 78 +
.../db/DMLShardingDataBasesOnlyTest.java | 174 +
...ectAggregateShardingDataBasesOnlyTest.java | 75 +
...electGroupByShardingDataBasesOnlyTest.java | 72 +
.../db/SelectShardingDataBasesOnlyTest.java | 97 +
...StatementDMLShardingDataBasesOnlyTest.java | 105 +
...ectAggregateShardingDataBasesOnlyTest.java | 43 +
...tementSelectShardingDataBasesOnlyTest.java | 82 +
...rdingBothDataBasesAndTablesDBUnitTest.java | 98 +
...DMLShardingBothDataBasesAndTablesTest.java | 185 +
...ateShardingBothDataBasesAndTablesTest.java | 75 +
...pByShardingBothDataBasesAndTablesTest.java | 72 +
...ectShardingBothDataBasesAndTablesTest.java | 111 +
...DMLShardingBothDataBasesAndTablesTest.java | 114 +
...ateShardingBothDataBasesAndTablesTest.java | 43 +
...ectShardingBothDataBasesAndTablesTest.java | 91 +
...leKeysModuloDatabaseShardingAlgorithm.java | 81 +
...tipleKeysModuloTableShardingAlgorithm.java | 80 +
...gleKeyModuloDatabaseShardingAlgorithm.java | 65 +
...SingleKeyModuloTableShardingAlgorithm.java | 65 +
.../AbstractShardingTablesOnlyDBUnitTest.java | 79 +
.../tbl/DMLShardingTablesOnlyTest.java | 196 +
...SelectAggregateShardingTablesOnlyTest.java | 75 +
.../SelectGroupByShardingTablesOnlyTest.java | 72 +
.../tbl/SelectShardingTablesOnlyTest.java | 112 +
.../StatementDMLShardingTablesOnlyTest.java | 113 +
...SelectAggregateShardingTablesOnlyTest.java | 43 +
...StatementSelectShardingTablesOnlyTest.java | 98 +
.../ddframe/rdb/sharding/api/AllApiTest.java | 51 +
.../rdb/sharding/api/DatabaseTypeTest.java | 42 +
.../sharding/api/ShardingDataSourceTest.java | 70 +
.../rdb/sharding/api/ShardingValueTest.java | 61 +
.../api/config/ShardingConfigurationTest.java | 90 +
.../api/rule/BindingTableRuleTest.java | 78 +
.../sharding/api/rule/DataSourceRuleTest.java | 63 +
.../sharding/api/rule/ShardingRuleTest.java | 207 +
.../rdb/sharding/api/rule/TableRuleTest.java | 105 +
.../api/rule/fixture/TestDataSource.java | 28 +
.../strategy/common/ShardingStrategyTest.java | 74 +
.../DatabaseShardingStrategyTest.java | 34 +
.../NoneDatabaseShardingAlgorithmTest.java | 60 +
.../TestMultipleKeysShardingAlgorithm.java | 33 +
.../TestSingleKeyShardingAlgorithm.java | 48 +
.../table/NoneTableShardingAlgorithmTest.java | 60 +
.../table/TableShardingStrategyTest.java | 34 +
.../rdb/sharding/jdbc/AllJDBCTest.java | 56 +
.../jdbc/ShardingPreparedStatementTest.java | 213 +
.../sharding/jdbc/ShardingStatementTest.java | 188 +
.../jdbc/adapter/ConnectionAdapterTest.java | 179 +
.../jdbc/adapter/DataSourceAdapterTest.java | 96 +
.../adapter/PreparedStatementAdapterTest.java | 287 +
.../jdbc/adapter/ResultSetAdapterTest.java | 152 +
.../adapter/ResultSetGetterAdapterTest.java | 428 ++
.../jdbc/adapter/StatementAdapterTest.java | 153 +
.../ResultSetUpdaterAdapterTest.java | 478 ++
.../UnsupportedOperationConnectionTest.java | 189 +
.../UnsupportedOperationDataSourceTest.java | 47 +
...pportedOperationPreparedStatementTest.java | 104 +
.../UnsupportedOperationResultSetTest.java | 248 +
.../UnsupportedOperationStatementTest.java | 122 +
.../jdbc/util/JdbcMethodInvocationTest.java | 37 +
.../rdb/sharding/merger/AllMergerTest.java | 48 +
.../merger/ResultSetQueryIndexTest.java | 47 +
.../sharding/merger/ResultSetUtilTest.java | 116 +
.../AccumulationAggregationUnitTest.java | 35 +
.../aggregation/AggregationResultSetTest.java | 107 +
.../aggregation/AvgAggregationUnitTest.java | 37 +
.../ComparableAggregationUnitTest.java | 44 +
.../ResultSetAggregationValueTest.java | 50 +
...ractUnsupportedOperationMockResultSet.java | 346 +
.../merger/fixture/MockResultSet.java | 115 +
.../merger/groupby/GroupByValueTest.java | 95 +
.../iterator/IteratorResultSetTest.java | 72 +
.../merger/orderby/OrderByResultSetTest.java | 74 +
.../merger/orderby/OrderByValueTest.java | 83 +
.../rdb/sharding/metrics/AllMetricsTest.java | 26 +
.../sharding/metrics/MetricsContextTest.java | 42 +
.../parser/AbstractBaseParseTest.java | 244 +
.../rdb/sharding/parser/AllParserTest.java | 41 +
.../sharding/parser/UnsupportedParseTest.java | 48 +
.../parser/jaxb/AggregationColumn.java | 53 +
.../rdb/sharding/parser/jaxb/Assert.java | 67 +
.../rdb/sharding/parser/jaxb/Asserts.java | 34 +
.../rdb/sharding/parser/jaxb/Condition.java | 46 +
.../parser/jaxb/ConditionContext.java | 34 +
.../sharding/parser/jaxb/GroupByColumn.java | 40 +
.../rdb/sharding/parser/jaxb/Limit.java | 37 +
.../sharding/parser/jaxb/OrderByColumn.java | 40 +
.../rdb/sharding/parser/jaxb/Table.java | 37 +
.../rdb/sharding/parser/jaxb/Value.java | 53 +
...LPreparedStatementForOneParameterTest.java | 52 +
...PreparedStatementForTowParametersTest.java | 52 +
.../parser/mysql/MySQLStatementTest.java | 53 +
.../sharding/parser/mysql/OrParseTest.java | 55 +
.../parser/result/SQLParsedResultTest.java | 75 +
.../result/merger/MergeContextTest.java | 41 +
.../router/AbstractBaseRouteSqlTest.java | 107 +
.../rdb/sharding/router/AllRouterTest.java | 38 +
.../ddframe/rdb/sharding/router/DMLTest.java | 45 +
.../router/SelectBindingTableTest.java | 47 +
.../router/SelectMixedTablesTest.java | 58 +
.../router/SelectSingleTableTest.java | 57 +
.../binding/BindingRoutingResultTest.java | 42 +
.../fixture/OrderAttrShardingAlgorithm.java | 57 +
.../fixture/OrderShardingAlgorithm.java | 64 +
.../router/mixed/CartesianResultTest.java | 40 +
.../single/SingleRoutingResultTest.java | 36 +
.../sharding/parser/mysql/or/select_or.xml | 123 +
.../preparedstatement/one_param/delete.xml | 15 +
.../preparedstatement/one_param/insert.xml | 18 +
.../preparedstatement/one_param/select.xml | 17 +
.../one_param/select_limit.xml | 12 +
.../preparedstatement/one_param/update.xml | 15 +
.../preparedstatement/two_params/select.xml | 16 +
.../two_params/select_limit.xml | 12 +
.../parser/mysql/statement/delete.xml | 31 +
.../parser/mysql/statement/insert.xml | 50 +
.../statement/multiple_tables_select.xml | 73 +
.../mysql/statement/select_aggregate.xml | 76 +
.../mysql/statement/select_group_by.xml | 27 +
.../parser/mysql/statement/select_limit.xml | 22 +
.../mysql/statement/select_order_by.xml | 33 +
.../parser/mysql/statement/simple_select.xml | 151 +
.../parser/mysql/statement/update.xml | 17 +
.../resources/integrate/dataset/Empty.xml | 4 +
.../dataset/db/expect/delete/db_0.xml | 3 +
.../dataset/db/expect/delete/db_1.xml | 3 +
.../dataset/db/expect/delete/db_2.xml | 3 +
.../dataset/db/expect/delete/db_3.xml | 3 +
.../dataset/db/expect/delete/db_4.xml | 3 +
.../dataset/db/expect/delete/db_5.xml | 3 +
.../dataset/db/expect/delete/db_6.xml | 3 +
.../dataset/db/expect/delete/db_7.xml | 3 +
.../dataset/db/expect/delete/db_8.xml | 3 +
.../dataset/db/expect/delete/db_9.xml | 3 +
.../dataset/db/expect/insert/db_0.xml | 3 +
.../dataset/db/expect/insert/db_1.xml | 3 +
.../dataset/db/expect/insert/db_2.xml | 3 +
.../dataset/db/expect/insert/db_3.xml | 3 +
.../dataset/db/expect/insert/db_4.xml | 3 +
.../dataset/db/expect/insert/db_5.xml | 3 +
.../dataset/db/expect/insert/db_6.xml | 3 +
.../dataset/db/expect/insert/db_7.xml | 3 +
.../dataset/db/expect/insert/db_8.xml | 3 +
.../dataset/db/expect/insert/db_9.xml | 3 +
.../select/SelectBetweenWithSingleTable.xml | 6 +
.../select/SelectEqualsWithSingleTable_0.xml | 3 +
.../select/SelectEqualsWithSingleTable_1.xml | 3 +
.../select/SelectGroupByWithBindingTable.xml | 4 +
.../SelectGroupByWithoutGroupedColumn.xml | 4 +
.../select/SelectInWithSingleTable_0.xml | 4 +
.../select/SelectInWithSingleTable_1.xml | 3 +
.../select/SelectLimitWithBindingTable.xml | 4 +
...lectLimitWithBindingTableWithoutOffset.xml | 4 +
.../expect/select/SelectNoShardingTable.xml | 82 +
.../db/expect/select_aggregate/SelectAvg.xml | 3 +
.../expect/select_aggregate/SelectCount.xml | 3 +
.../SelectCountWithBindingTable_0.xml | 3 +
.../SelectCountWithBindingTable_1.xml | 3 +
.../db/expect/select_aggregate/SelectMax.xml | 3 +
.../db/expect/select_aggregate/SelectMin.xml | 3 +
.../db/expect/select_aggregate/SelectSum.xml | 3 +
.../db/expect/select_groupby/SelectAvg.xml | 22 +
.../db/expect/select_groupby/SelectCount.xml | 22 +
.../db/expect/select_groupby/SelectMax.xml | 22 +
.../db/expect/select_groupby/SelectMin.xml | 22 +
.../select_groupby/SelectOrderByDesc.xml | 22 +
.../db/expect/select_groupby/SelectSum.xml | 22 +
.../dataset/db/expect/update/db_0.xml | 6 +
.../dataset/db/expect/update/db_1.xml | 6 +
.../dataset/db/expect/update/db_2.xml | 6 +
.../dataset/db/expect/update/db_3.xml | 6 +
.../dataset/db/expect/update/db_4.xml | 6 +
.../dataset/db/expect/update/db_5.xml | 6 +
.../dataset/db/expect/update/db_6.xml | 6 +
.../dataset/db/expect/update/db_7.xml | 6 +
.../dataset/db/expect/update/db_8.xml | 6 +
.../dataset/db/expect/update/db_9.xml | 6 +
.../integrate/dataset/db/init/db_0.xml | 15 +
.../integrate/dataset/db/init/db_1.xml | 15 +
.../integrate/dataset/db/init/db_2.xml | 15 +
.../integrate/dataset/db/init/db_3.xml | 15 +
.../integrate/dataset/db/init/db_4.xml | 15 +
.../integrate/dataset/db/init/db_5.xml | 15 +
.../integrate/dataset/db/init/db_6.xml | 15 +
.../integrate/dataset/db/init/db_7.xml | 15 +
.../integrate/dataset/db/init/db_8.xml | 15 +
.../integrate/dataset/db/init/db_9.xml | 15 +
.../dataset/dbtbl/expect/delete/dbtbl_0.xml | 12 +
.../dataset/dbtbl/expect/delete/dbtbl_1.xml | 12 +
.../dataset/dbtbl/expect/delete/dbtbl_2.xml | 12 +
.../dataset/dbtbl/expect/delete/dbtbl_3.xml | 12 +
.../dataset/dbtbl/expect/delete/dbtbl_4.xml | 12 +
.../dataset/dbtbl/expect/delete/dbtbl_5.xml | 12 +
.../dataset/dbtbl/expect/delete/dbtbl_6.xml | 12 +
.../dataset/dbtbl/expect/delete/dbtbl_7.xml | 12 +
.../dataset/dbtbl/expect/delete/dbtbl_8.xml | 12 +
.../dataset/dbtbl/expect/delete/dbtbl_9.xml | 12 +
.../dataset/dbtbl/expect/insert/dbtbl_0.xml | 12 +
.../dataset/dbtbl/expect/insert/dbtbl_1.xml | 12 +
.../dataset/dbtbl/expect/insert/dbtbl_2.xml | 12 +
.../dataset/dbtbl/expect/insert/dbtbl_3.xml | 12 +
.../dataset/dbtbl/expect/insert/dbtbl_4.xml | 12 +
.../dataset/dbtbl/expect/insert/dbtbl_5.xml | 12 +
.../dataset/dbtbl/expect/insert/dbtbl_6.xml | 12 +
.../dataset/dbtbl/expect/insert/dbtbl_7.xml | 12 +
.../dataset/dbtbl/expect/insert/dbtbl_8.xml | 12 +
.../dataset/dbtbl/expect/insert/dbtbl_9.xml | 12 +
.../select/SelectBetweenWithSingleTable.xml | 12 +
.../select/SelectEqualsWithSingleTable_0.xml | 3 +
.../select/SelectEqualsWithSingleTable_1.xml | 3 +
.../select/SelectGroupByWithBindingTable.xml | 4 +
.../SelectGroupByWithoutGroupedColumn.xml | 4 +
.../select/SelectInWithSingleTable_0.xml | 4 +
.../select/SelectInWithSingleTable_1.xml | 3 +
.../select/SelectLimitWithBindingTable.xml | 4 +
...lectLimitWithBindingTableWithoutOffset.xml | 4 +
.../expect/select/SelectNoShardingTable.xml | 202 +
.../SelectWithBingdingTableAndConfigTable.xml | 22 +
.../expect/select_aggregate/SelectAvg.xml | 3 +
.../expect/select_aggregate/SelectCount.xml | 3 +
.../SelectCountWithBindingTable_0.xml | 3 +
.../SelectCountWithBindingTable_1.xml | 3 +
.../expect/select_aggregate/SelectMax.xml | 3 +
.../expect/select_aggregate/SelectMin.xml | 3 +
.../expect/select_aggregate/SelectSum.xml | 3 +
.../dbtbl/expect/select_groupby/SelectAvg.xml | 12 +
.../expect/select_groupby/SelectCount.xml | 12 +
.../dbtbl/expect/select_groupby/SelectMax.xml | 12 +
.../dbtbl/expect/select_groupby/SelectMin.xml | 12 +
.../select_groupby/SelectOrderByDesc.xml | 12 +
.../dbtbl/expect/select_groupby/SelectSum.xml | 12 +
.../dataset/dbtbl/expect/update/dbtbl_0.xml | 12 +
.../dataset/dbtbl/expect/update/dbtbl_1.xml | 12 +
.../dataset/dbtbl/expect/update/dbtbl_2.xml | 12 +
.../dataset/dbtbl/expect/update/dbtbl_3.xml | 12 +
.../dataset/dbtbl/expect/update/dbtbl_4.xml | 12 +
.../dataset/dbtbl/expect/update/dbtbl_5.xml | 12 +
.../dataset/dbtbl/expect/update/dbtbl_6.xml | 12 +
.../dataset/dbtbl/expect/update/dbtbl_7.xml | 12 +
.../dataset/dbtbl/expect/update/dbtbl_8.xml | 12 +
.../dataset/dbtbl/expect/update/dbtbl_9.xml | 12 +
.../integrate/dataset/dbtbl/init/dbtbl_0.xml | 35 +
.../integrate/dataset/dbtbl/init/dbtbl_1.xml | 35 +
.../integrate/dataset/dbtbl/init/dbtbl_2.xml | 35 +
.../integrate/dataset/dbtbl/init/dbtbl_3.xml | 35 +
.../integrate/dataset/dbtbl/init/dbtbl_4.xml | 35 +
.../integrate/dataset/dbtbl/init/dbtbl_5.xml | 35 +
.../integrate/dataset/dbtbl/init/dbtbl_6.xml | 35 +
.../integrate/dataset/dbtbl/init/dbtbl_7.xml | 35 +
.../integrate/dataset/dbtbl/init/dbtbl_8.xml | 35 +
.../integrate/dataset/dbtbl/init/dbtbl_9.xml | 35 +
.../dataset/tbl/expect/delete/db_single.xml | 12 +
.../dataset/tbl/expect/insert/db_single.xml | 12 +
.../select/SelectBetweenWithSingleTable.xml | 12 +
.../select/SelectEqualsWithSingleTable_0.xml | 3 +
.../select/SelectEqualsWithSingleTable_1.xml | 3 +
.../select/SelectGroupByWithBindingTable.xml | 4 +
.../SelectGroupByWithoutGroupedColumn.xml | 4 +
.../select/SelectInWithSingleTable_0.xml | 4 +
.../select/SelectInWithSingleTable_1.xml | 3 +
.../select/SelectLimitWithBindingTable.xml | 4 +
...lectLimitWithBindingTableWithoutOffset.xml | 4 +
.../expect/select/SelectNoShardingTable.xml | 42 +
.../SelectWithBingdingTableAndConfigTable.xml | 22 +
.../tbl/expect/select_aggregate/SelectAvg.xml | 3 +
.../expect/select_aggregate/SelectCount.xml | 3 +
.../SelectCountWithBindingTable_0.xml | 3 +
.../SelectCountWithBindingTable_1.xml | 3 +
.../tbl/expect/select_aggregate/SelectMax.xml | 3 +
.../tbl/expect/select_aggregate/SelectMin.xml | 3 +
.../tbl/expect/select_aggregate/SelectSum.xml | 3 +
.../tbl/expect/select_groupby/SelectAvg.xml | 4 +
.../tbl/expect/select_groupby/SelectCount.xml | 4 +
.../tbl/expect/select_groupby/SelectMax.xml | 4 +
.../tbl/expect/select_groupby/SelectMin.xml | 4 +
.../select_groupby/SelectOrderByDesc.xml | 4 +
.../tbl/expect/select_groupby/SelectSum.xml | 4 +
.../dataset/tbl/expect/update/db_single.xml | 22 +
.../integrate/dataset/tbl/init/db_single.xml | 65 +
.../resources/integrate/schema/all_schema.sql | 295 +
.../resources/integrate/schema/db/db_0.sql | 4 +
.../resources/integrate/schema/db/db_1.sql | 4 +
.../resources/integrate/schema/db/db_2.sql | 4 +
.../resources/integrate/schema/db/db_3.sql | 4 +
.../resources/integrate/schema/db/db_4.sql | 4 +
.../resources/integrate/schema/db/db_5.sql | 4 +
.../resources/integrate/schema/db/db_6.sql | 4 +
.../resources/integrate/schema/db/db_7.sql | 4 +
.../resources/integrate/schema/db/db_8.sql | 4 +
.../resources/integrate/schema/db/db_9.sql | 4 +
.../integrate/schema/dbtbl/dbtbl_0.sql | 23 +
.../integrate/schema/dbtbl/dbtbl_1.sql | 23 +
.../integrate/schema/dbtbl/dbtbl_2.sql | 23 +
.../integrate/schema/dbtbl/dbtbl_3.sql | 23 +
.../integrate/schema/dbtbl/dbtbl_4.sql | 23 +
.../integrate/schema/dbtbl/dbtbl_5.sql | 23 +
.../integrate/schema/dbtbl/dbtbl_6.sql | 23 +
.../integrate/schema/dbtbl/dbtbl_7.sql | 23 +
.../integrate/schema/dbtbl/dbtbl_8.sql | 23 +
.../integrate/schema/dbtbl/dbtbl_9.sql | 23 +
.../integrate/schema/tbl/db_single.sql | 23 +
.../src/test/resources/logback-test.xml | 23 +
sharding-jdbc-doc/config.toml | 24 +
.../content/img/AlgorithmClass.900.png | Bin 0 -> 67255 bytes
.../content/img/AlgorithmClass.png | Bin 0 -> 28716 bytes
.../content/img/StrategyClass.900.png | Bin 0 -> 63651 bytes
.../content/img/StrategyClass.png | Bin 0 -> 19166 bytes
.../content/img/architecture.png | Bin 0 -> 188679 bytes
sharding-jdbc-doc/content/img/execute.png | Bin 0 -> 113012 bytes
sharding-jdbc-doc/content/img/intro-bg.svg | 65 +
sharding-jdbc-doc/content/img/merge.png | Bin 0 -> 235192 bytes
sharding-jdbc-doc/content/img/parse.png | Bin 0 -> 144333 bytes
sharding-jdbc-doc/content/img/route.png | Bin 0 -> 106562 bytes
sharding-jdbc-doc/content/index/index.md | 96 +
.../content/post/architecture.md | 16 +
sharding-jdbc-doc/content/post/features.md | 43 +
sharding-jdbc-doc/content/post/restriction.md | 57 +
sharding-jdbc-doc/content/post/roadmap.md | 17 +
sharding-jdbc-doc/content/post/user_guide.md | 385 +
sharding-jdbc-doc/layouts/_default/list.html | 4 +
.../layouts/_default/single.html | 28 +
sharding-jdbc-doc/layouts/index.html | 5 +
.../layouts/partials/footer.html | 15 +
sharding-jdbc-doc/layouts/partials/head.html | 25 +
.../layouts/partials/header.html | 29 +
sharding-jdbc-doc/layouts/partials/js.html | 28 +
sharding-jdbc-doc/layouts/partials/nav.html | 31 +
sharding-jdbc-doc/layouts/partials/pages.html | 0
.../layouts/partials/services.html | 36 +
.../layouts/partials/template.css | 36 +
sharding-jdbc-doc/static/css/bootstrap.css | 6203 +++++++++++++++++
.../static/css/bootstrap.min.css | 5 +
sharding-jdbc-doc/static/css/landing-page.css | 209 +
sharding-jdbc-doc/static/css/prism.css | 139 +
sharding-jdbc-doc/static/css/table.css | 11 +
.../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20335 bytes
.../fonts/glyphicons-halflings-regular.svg | 229 +
.../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 41280 bytes
.../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23320 bytes
sharding-jdbc-doc/static/js/bootstrap.js | 2114 ++++++
sharding-jdbc-doc/static/js/bootstrap.min.js | 6 +
sharding-jdbc-doc/static/js/prism.js | 5 +
sharding-jdbc-example/pom.xml | 173 +
.../sharding-jdbc-example-jdbc/pom.xml | 9 +
.../rdb/sharding/example/jdbc/Main.java | 107 +
.../ModuloDatabaseShardingAlgorithm.java | 65 +
.../ModuloTableShardingAlgorithm.java | 65 +
.../src/main/resources/all_schema.sql | 56 +
.../src/main/resources/logback.xml | 21 +
.../sharding-jdbc-example-jpa/pom.xml | 44 +
.../rdb/sharding/example/jdbc/Main.java | 52 +
...gleKeyModuloDatabaseShardingAlgorithm.java | 66 +
...SingleKeyModuloTableShardingAlgorithm.java | 66 +
.../sharding/example/jdbc/entity/Order.java | 71 +
.../jdbc/repository/OrderRepository.java | 35 +
.../jdbc/repository/OrderRepositoryImpl.java | 62 +
.../main/resources/META-INF/jpaContext.xml | 38 +
.../resources/META-INF/shardingContext.xml | 69 +
.../src/main/resources/all_schema.sql | 56 +
.../src/main/resources/logback.xml | 21 +
.../sharding-jdbc-example-mybatis/pom.xml | 36 +
.../rdb/sharding/example/jdbc/Main.java | 52 +
...gleKeyModuloDatabaseShardingAlgorithm.java | 66 +
...SingleKeyModuloTableShardingAlgorithm.java | 66 +
.../sharding/example/jdbc/entity/Order.java | 56 +
.../jdbc/repository/OrderRepository.java | 37 +
.../META-INF/mybatis/mappers/OrderMapper.xml | 54 +
.../resources/META-INF/mybatisContext.xml | 18 +
.../resources/META-INF/shardingContext.xml | 69 +
.../src/main/resources/all_schema.sql | 56 +
.../src/main/resources/logback.xml | 28 +
src/resources/dd_checks.xml | 152 +
src/resources/dd_pmd.xml | 107 +
499 files changed, 36077 insertions(+), 9 deletions(-)
create mode 100644 README.md
create mode 100644 pom.xml
create mode 100644 sharding-jdbc-core/pom.xml
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/DatabaseType.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/ShardingDataSource.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/ShardingValue.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/config/ShardingConfiguration.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/config/ShardingConfigurationConstant.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/BindingTableRule.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataNode.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataSourceRule.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/ShardingRule.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/TableRule.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/MultipleKeysShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingStrategy.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/SingleKeyShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/DatabaseShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/DatabaseShardingStrategy.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/MultipleKeysDatabaseShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/NoneDatabaseShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/SingleKeyDatabaseShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/MultipleKeysTableShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/NoneTableShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/SingleKeyTableShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/TableShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/TableShardingStrategy.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/exception/DatabaseTypeUnsupportedException.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/exception/SQLParserException.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/exception/ShardingJdbcException.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/ExecuteUnit.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/ExecutorEngine.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/MergeUnit.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/PreparedStatementExecutor.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/StatementExecutor.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/AbstractShardingResultSet.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingConnection.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatement.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatement.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractConnectionAdapter.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractDataSourceAdapter.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractPreparedStatementAdapter.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractResultSetAdapter.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractResultSetGetterAdapter.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractStatementAdapter.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/WrapperAdapter.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractResultSetUpdaterAdapter.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationConnection.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationDataSource.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationPreparedStatement.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationStatement.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/util/JdbcMethodInvocation.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/ResultSetFactory.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AbstractAggregationUnit.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AccumulationAggregationUnit.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationInvokeHandler.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationResultSet.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationUnit.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationUnitFactory.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationValue.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AvgAggregationUnit.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/ComparableAggregationUnit.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/ResultSetAggregationValue.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/common/AbstractMergerInvokeHandler.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/common/ResultSetQueryIndex.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/common/ResultSetUtil.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByInvokeHandler.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByKey.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByResultSet.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByValue.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/iterator/IteratorResultSet.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/orderby/OrderByResultSet.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/orderby/OrderByValue.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/metrics/MetricsContext.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/SQLParseEngine.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/SQLParserFactory.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/SQLVisitorRegistry.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResult.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/AggregationColumn.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/GroupByColumn.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/Limit.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/MergeContext.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/OrderByColumn.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/Condition.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/ConditionContext.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/RouteContext.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/SQLBuilder.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/Table.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/ParseContext.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/SQLVisitor.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/VisitorLogProxy.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/basic/mysql/AbstractMySQLVisitor.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/basic/mysql/MySQLDeleteVisitor.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/basic/mysql/MySQLInsertVisitor.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/basic/mysql/MySQLSelectVisitor.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/basic/mysql/MySQLUpdateVisitor.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/or/OrParser.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/or/OrVisitor.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/or/node/AbstractOrASTNode.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/or/node/CompositeOrASTNode.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/visitor/or/node/SimpleOrASTNode.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/RoutingResult.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/SQLExecutionUnit.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/SQLRouteEngine.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/SQLRouteResult.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/binding/BindingRoutingDataSource.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/binding/BindingRoutingResult.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/binding/BindingRoutingTableFactor.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/binding/BindingTablesRouter.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/mixed/CartesianDataSource.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/mixed/CartesianResult.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/mixed/CartesianTableReference.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/mixed/CartesianTablesRouter.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/mixed/MixedTablesRouter.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/single/SingleRoutingDataSource.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/single/SingleRoutingResult.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/single/SingleRoutingTableFactor.java
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/single/SingleTableRouter.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/AllTests.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/AbstractDBUnitTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/AllIntegrateTests.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/DataBaseEnvironment.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/ShardingJdbcDatabaseTester.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/db/AbstractShardingDataBasesOnlyDBUnitTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/db/DMLShardingDataBasesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/db/SelectAggregateShardingDataBasesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/db/SelectGroupByShardingDataBasesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/db/SelectShardingDataBasesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/db/StatementDMLShardingDataBasesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/db/StatementSelectAggregateShardingDataBasesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/db/StatementSelectShardingDataBasesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/dbtbl/AbstractShardingBothDataBasesAndTablesDBUnitTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/dbtbl/DMLShardingBothDataBasesAndTablesTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/dbtbl/SelectAggregateShardingBothDataBasesAndTablesTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/dbtbl/SelectGroupByShardingBothDataBasesAndTablesTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/dbtbl/SelectShardingBothDataBasesAndTablesTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/dbtbl/StatementDMLShardingBothDataBasesAndTablesTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/dbtbl/StatementSelectAggregateShardingBothDataBasesAndTablesTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/dbtbl/StatementSelectShardingBothDataBasesAndTablesTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/fixture/MultipleKeysModuloDatabaseShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/fixture/MultipleKeysModuloTableShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/fixture/SingleKeyModuloDatabaseShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/fixture/SingleKeyModuloTableShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/tbl/AbstractShardingTablesOnlyDBUnitTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/tbl/DMLShardingTablesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/tbl/SelectAggregateShardingTablesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/tbl/SelectGroupByShardingTablesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/tbl/SelectShardingTablesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/tbl/StatementDMLShardingTablesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/tbl/StatementSelectAggregateShardingTablesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/tbl/StatementSelectShardingTablesOnlyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/AllApiTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/DatabaseTypeTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/ShardingDataSourceTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/ShardingValueTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/config/ShardingConfigurationTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/BindingTableRuleTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataSourceRuleTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/ShardingRuleTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/TableRuleTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/fixture/TestDataSource.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingStrategyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/DatabaseShardingStrategyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/NoneDatabaseShardingAlgorithmTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/fixture/TestMultipleKeysShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/fixture/TestSingleKeyShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/NoneTableShardingAlgorithmTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/TableShardingStrategyTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/AllJDBCTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatementTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatementTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/ConnectionAdapterTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/DataSourceAdapterTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/PreparedStatementAdapterTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/ResultSetAdapterTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/ResultSetGetterAdapterTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/StatementAdapterTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/ResultSetUpdaterAdapterTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/UnsupportedOperationConnectionTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/UnsupportedOperationDataSourceTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/UnsupportedOperationPreparedStatementTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/UnsupportedOperationResultSetTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/UnsupportedOperationStatementTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/util/JdbcMethodInvocationTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/AllMergerTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/ResultSetQueryIndexTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/ResultSetUtilTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AccumulationAggregationUnitTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationResultSetTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AvgAggregationUnitTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/ComparableAggregationUnitTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/ResultSetAggregationValueTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/fixture/AbstractUnsupportedOperationMockResultSet.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/fixture/MockResultSet.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByValueTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/iterator/IteratorResultSetTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/orderby/OrderByResultSetTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/orderby/OrderByValueTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/metrics/AllMetricsTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/metrics/MetricsContextTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/AbstractBaseParseTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/AllParserTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/UnsupportedParseTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/jaxb/AggregationColumn.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/jaxb/Assert.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/jaxb/Asserts.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/jaxb/Condition.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/jaxb/ConditionContext.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/jaxb/GroupByColumn.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/jaxb/Limit.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/jaxb/OrderByColumn.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/jaxb/Table.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/jaxb/Value.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/mysql/MySQLPreparedStatementForOneParameterTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/mysql/MySQLPreparedStatementForTowParametersTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/mysql/MySQLStatementTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/mysql/OrParseTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResultTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/MergeContextTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/router/AbstractBaseRouteSqlTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/router/AllRouterTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/router/DMLTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/router/SelectBindingTableTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/router/SelectMixedTablesTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/router/SelectSingleTableTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/router/binding/BindingRoutingResultTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/router/fixture/OrderAttrShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/router/fixture/OrderShardingAlgorithm.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/router/mixed/CartesianResultTest.java
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/router/single/SingleRoutingResultTest.java
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/or/select_or.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/preparedstatement/one_param/delete.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/preparedstatement/one_param/insert.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/preparedstatement/one_param/select.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/preparedstatement/one_param/select_limit.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/preparedstatement/one_param/update.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/preparedstatement/two_params/select.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/preparedstatement/two_params/select_limit.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/statement/delete.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/statement/insert.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/statement/multiple_tables_select.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/statement/select_aggregate.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/statement/select_group_by.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/statement/select_limit.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/statement/select_order_by.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/statement/simple_select.xml
create mode 100644 sharding-jdbc-core/src/test/resources/com/dangdang/ddframe/rdb/sharding/parser/mysql/statement/update.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/Empty.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/delete/db_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/delete/db_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/delete/db_2.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/delete/db_3.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/delete/db_4.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/delete/db_5.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/delete/db_6.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/delete/db_7.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/delete/db_8.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/delete/db_9.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/insert/db_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/insert/db_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/insert/db_2.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/insert/db_3.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/insert/db_4.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/insert/db_5.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/insert/db_6.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/insert/db_7.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/insert/db_8.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/insert/db_9.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select/SelectBetweenWithSingleTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select/SelectEqualsWithSingleTable_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select/SelectEqualsWithSingleTable_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select/SelectGroupByWithBindingTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select/SelectGroupByWithoutGroupedColumn.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select/SelectInWithSingleTable_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select/SelectInWithSingleTable_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select/SelectLimitWithBindingTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select/SelectLimitWithBindingTableWithoutOffset.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select/SelectNoShardingTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_aggregate/SelectAvg.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_aggregate/SelectCount.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_aggregate/SelectCountWithBindingTable_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_aggregate/SelectCountWithBindingTable_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_aggregate/SelectMax.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_aggregate/SelectMin.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_aggregate/SelectSum.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_groupby/SelectAvg.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_groupby/SelectCount.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_groupby/SelectMax.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_groupby/SelectMin.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_groupby/SelectOrderByDesc.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/select_groupby/SelectSum.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/update/db_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/update/db_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/update/db_2.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/update/db_3.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/update/db_4.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/update/db_5.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/update/db_6.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/update/db_7.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/update/db_8.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/expect/update/db_9.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/init/db_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/init/db_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/init/db_2.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/init/db_3.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/init/db_4.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/init/db_5.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/init/db_6.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/init/db_7.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/init/db_8.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/db/init/db_9.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/delete/dbtbl_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/delete/dbtbl_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/delete/dbtbl_2.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/delete/dbtbl_3.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/delete/dbtbl_4.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/delete/dbtbl_5.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/delete/dbtbl_6.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/delete/dbtbl_7.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/delete/dbtbl_8.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/delete/dbtbl_9.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/insert/dbtbl_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/insert/dbtbl_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/insert/dbtbl_2.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/insert/dbtbl_3.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/insert/dbtbl_4.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/insert/dbtbl_5.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/insert/dbtbl_6.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/insert/dbtbl_7.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/insert/dbtbl_8.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/insert/dbtbl_9.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select/SelectBetweenWithSingleTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select/SelectEqualsWithSingleTable_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select/SelectEqualsWithSingleTable_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select/SelectGroupByWithBindingTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select/SelectGroupByWithoutGroupedColumn.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select/SelectInWithSingleTable_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select/SelectInWithSingleTable_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select/SelectLimitWithBindingTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select/SelectLimitWithBindingTableWithoutOffset.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select/SelectNoShardingTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select/SelectWithBingdingTableAndConfigTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_aggregate/SelectAvg.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_aggregate/SelectCount.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_aggregate/SelectCountWithBindingTable_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_aggregate/SelectCountWithBindingTable_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_aggregate/SelectMax.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_aggregate/SelectMin.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_aggregate/SelectSum.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_groupby/SelectAvg.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_groupby/SelectCount.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_groupby/SelectMax.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_groupby/SelectMin.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_groupby/SelectOrderByDesc.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/select_groupby/SelectSum.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/update/dbtbl_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/update/dbtbl_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/update/dbtbl_2.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/update/dbtbl_3.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/update/dbtbl_4.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/update/dbtbl_5.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/update/dbtbl_6.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/update/dbtbl_7.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/update/dbtbl_8.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/expect/update/dbtbl_9.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/init/dbtbl_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/init/dbtbl_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/init/dbtbl_2.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/init/dbtbl_3.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/init/dbtbl_4.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/init/dbtbl_5.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/init/dbtbl_6.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/init/dbtbl_7.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/init/dbtbl_8.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/dbtbl/init/dbtbl_9.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/delete/db_single.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/insert/db_single.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select/SelectBetweenWithSingleTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select/SelectEqualsWithSingleTable_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select/SelectEqualsWithSingleTable_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select/SelectGroupByWithBindingTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select/SelectGroupByWithoutGroupedColumn.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select/SelectInWithSingleTable_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select/SelectInWithSingleTable_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select/SelectLimitWithBindingTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select/SelectLimitWithBindingTableWithoutOffset.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select/SelectNoShardingTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select/SelectWithBingdingTableAndConfigTable.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_aggregate/SelectAvg.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_aggregate/SelectCount.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_aggregate/SelectCountWithBindingTable_0.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_aggregate/SelectCountWithBindingTable_1.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_aggregate/SelectMax.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_aggregate/SelectMin.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_aggregate/SelectSum.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_groupby/SelectAvg.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_groupby/SelectCount.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_groupby/SelectMax.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_groupby/SelectMin.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_groupby/SelectOrderByDesc.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/select_groupby/SelectSum.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/expect/update/db_single.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/dataset/tbl/init/db_single.xml
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/all_schema.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/db/db_0.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/db/db_1.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/db/db_2.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/db/db_3.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/db/db_4.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/db/db_5.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/db/db_6.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/db/db_7.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/db/db_8.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/db/db_9.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/dbtbl/dbtbl_0.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/dbtbl/dbtbl_1.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/dbtbl/dbtbl_2.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/dbtbl/dbtbl_3.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/dbtbl/dbtbl_4.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/dbtbl/dbtbl_5.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/dbtbl/dbtbl_6.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/dbtbl/dbtbl_7.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/dbtbl/dbtbl_8.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/dbtbl/dbtbl_9.sql
create mode 100644 sharding-jdbc-core/src/test/resources/integrate/schema/tbl/db_single.sql
create mode 100644 sharding-jdbc-core/src/test/resources/logback-test.xml
create mode 100644 sharding-jdbc-doc/config.toml
create mode 100644 sharding-jdbc-doc/content/img/AlgorithmClass.900.png
create mode 100644 sharding-jdbc-doc/content/img/AlgorithmClass.png
create mode 100644 sharding-jdbc-doc/content/img/StrategyClass.900.png
create mode 100644 sharding-jdbc-doc/content/img/StrategyClass.png
create mode 100644 sharding-jdbc-doc/content/img/architecture.png
create mode 100644 sharding-jdbc-doc/content/img/execute.png
create mode 100644 sharding-jdbc-doc/content/img/intro-bg.svg
create mode 100644 sharding-jdbc-doc/content/img/merge.png
create mode 100644 sharding-jdbc-doc/content/img/parse.png
create mode 100644 sharding-jdbc-doc/content/img/route.png
create mode 100644 sharding-jdbc-doc/content/index/index.md
create mode 100644 sharding-jdbc-doc/content/post/architecture.md
create mode 100644 sharding-jdbc-doc/content/post/features.md
create mode 100644 sharding-jdbc-doc/content/post/restriction.md
create mode 100644 sharding-jdbc-doc/content/post/roadmap.md
create mode 100644 sharding-jdbc-doc/content/post/user_guide.md
create mode 100644 sharding-jdbc-doc/layouts/_default/list.html
create mode 100644 sharding-jdbc-doc/layouts/_default/single.html
create mode 100644 sharding-jdbc-doc/layouts/index.html
create mode 100644 sharding-jdbc-doc/layouts/partials/footer.html
create mode 100644 sharding-jdbc-doc/layouts/partials/head.html
create mode 100644 sharding-jdbc-doc/layouts/partials/header.html
create mode 100644 sharding-jdbc-doc/layouts/partials/js.html
create mode 100644 sharding-jdbc-doc/layouts/partials/nav.html
create mode 100644 sharding-jdbc-doc/layouts/partials/pages.html
create mode 100644 sharding-jdbc-doc/layouts/partials/services.html
create mode 100644 sharding-jdbc-doc/layouts/partials/template.css
create mode 100644 sharding-jdbc-doc/static/css/bootstrap.css
create mode 100644 sharding-jdbc-doc/static/css/bootstrap.min.css
create mode 100644 sharding-jdbc-doc/static/css/landing-page.css
create mode 100644 sharding-jdbc-doc/static/css/prism.css
create mode 100644 sharding-jdbc-doc/static/css/table.css
create mode 100644 sharding-jdbc-doc/static/fonts/glyphicons-halflings-regular.eot
create mode 100644 sharding-jdbc-doc/static/fonts/glyphicons-halflings-regular.svg
create mode 100644 sharding-jdbc-doc/static/fonts/glyphicons-halflings-regular.ttf
create mode 100644 sharding-jdbc-doc/static/fonts/glyphicons-halflings-regular.woff
create mode 100644 sharding-jdbc-doc/static/js/bootstrap.js
create mode 100644 sharding-jdbc-doc/static/js/bootstrap.min.js
create mode 100644 sharding-jdbc-doc/static/js/prism.js
create mode 100644 sharding-jdbc-example/pom.xml
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jdbc/pom.xml
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jdbc/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/Main.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jdbc/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/algorithm/ModuloDatabaseShardingAlgorithm.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jdbc/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/algorithm/ModuloTableShardingAlgorithm.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jdbc/src/main/resources/all_schema.sql
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jdbc/src/main/resources/logback.xml
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jpa/pom.xml
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jpa/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/Main.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jpa/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/algorithm/SingleKeyModuloDatabaseShardingAlgorithm.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jpa/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/algorithm/SingleKeyModuloTableShardingAlgorithm.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jpa/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/entity/Order.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jpa/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/repository/OrderRepository.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jpa/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/repository/OrderRepositoryImpl.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jpa/src/main/resources/META-INF/jpaContext.xml
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jpa/src/main/resources/META-INF/shardingContext.xml
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jpa/src/main/resources/all_schema.sql
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-jpa/src/main/resources/logback.xml
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-mybatis/pom.xml
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-mybatis/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/Main.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-mybatis/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/algorithm/SingleKeyModuloDatabaseShardingAlgorithm.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-mybatis/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/algorithm/SingleKeyModuloTableShardingAlgorithm.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-mybatis/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/entity/Order.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-mybatis/src/main/java/com/dangdang/ddframe/rdb/sharding/example/jdbc/repository/OrderRepository.java
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-mybatis/src/main/resources/META-INF/mybatis/mappers/OrderMapper.xml
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-mybatis/src/main/resources/META-INF/mybatisContext.xml
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-mybatis/src/main/resources/META-INF/shardingContext.xml
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-mybatis/src/main/resources/all_schema.sql
create mode 100644 sharding-jdbc-example/sharding-jdbc-example-mybatis/src/main/resources/logback.xml
create mode 100644 src/resources/dd_checks.xml
create mode 100644 src/resources/dd_pmd.xml
diff --git a/.gitignore b/.gitignore
index 32858aad3c383..f79a22e5b1f11 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,32 @@
-*.class
-
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
-
-# Package Files #
+# maven ignore
+target/
*.jar
*.war
-*.ear
+*.zip
+*.tar
+*.tar.gz
+
+# eclipse ignore
+.settings/
+.project
+.classpath
+
+# idea ignore
+.idea/
+*.ipr
+*.iml
+*.iws
+
+# temp ignore
+logs/
+*.doc
+*.log
+*.cache
+*.diff
+*.patch
+*.tmp
+
+# system ignore
+.DS_Store
+Thumbs.db
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000..5617aead126fc
--- /dev/null
+++ b/README.md
@@ -0,0 +1,91 @@
+# 主要贡献者
+
+* 张亮 [当当](http://www.dangdang.com/) zhangliang@dangdang.com
+* 高洪涛 [当当](http://www.dangdang.com/) gaohongtao@dangdang.com
+* 曹昊 [当当](http://www.dangdang.com/) caohao@dangdang.com
+* 岳令 [当当](http://www.dangdang.com/) yueling@dangdang.com
+
+**讨论QQ群:**xxx(不限于Sharding-JDBC,包括分布式,数据库相关以及其他互联网技术交流)
+
+# 简介
+`Sharding-JDBC`是当当应用框架`ddframe`中,关系型数据库模块`dd-rdb`中分离出来的数据库水平扩展框架,即透明化数据库分库分表访问。
+
+`Sharding-JDBC`直接封装`JDBC API`,可以理解为增强版的`JDBC`驱动,旧代码迁移成本几乎为零:
+
+* 可适用于任何基于`java`的`ORM`框架,如:`JPA`, `Hibernate`, `Mybatis`, `Spring JDBC Template`或直接使用`JDBC`。
+* 可基于任何第三方的数据库连接池,如:`DBCP`, `C3P0`, `BoneCP`, `Druid`等。
+* 理论上可支持任意实现`JDBC`规范的数据库。虽然目前仅支持`MySQL`,但已有支持`Oracle`,`SQLServer`,`DB2`等数据库的计划。
+
+`Sharding-JDBC`定位为轻量级`java`框架,使用客户端直连数据库,以`jar`包形式提供服务,未使用中间层,无需额外部署,无其他依赖,`DBA`也无需改变原有的运维方式。`SQL`解析使用`Druid`解析器,是目前性能最高的`SQL`解析器。
+
+`Sharding-JDBC`功能灵活且全面:
+
+* 分片策略灵活,可支持`=`,`BETWEEN`,`IN`等多维度分片,也可支持多分片键共用。
+* `SQL`解析功能完善,支持聚合,分组,排序,`Limit`,`OR`等查询,并且支持`Binding Table`以及笛卡尔积的表查询。
+
+***
+
+以下是常见的分库分表产品和`Sharding-JDBC`的对比:
+
+| 功能 | Cobar(MyCAT) | Cobar-client | TDDL | Sharding-JDBC |
+| ------------- |:-------------:| -------------:| -----------:|---------------:|
+| 分库 | 有 | 有 | 未开源 | 有 |
+| 分表 | 无 | 无 | 未开源 | 有 |
+| 中间层 | 是 | 否 | 否 | 否 |
+| ORM支持 | 任意 | 仅MyBatis | 任意 | 任意 |
+| 数据库支持 | 仅MySQL | 任意 | 任意 | 任意 |
+| 异构语言 | 可 | 仅Java | 仅Java | 仅Java |
+| 外部依赖 | 无 | 无 | Diamond | 无 |
+
+***
+
+# 整体架构图
+
+![整体架构图1](../img/architecture.png)
+
+# Quick Start
+
+## 引入maven依赖
+```xml
+
+
+ com.dangdang
+ sharding-jdbc-core
+ 1.0.0
+
+```
+
+## 规则配置
+`Sharding-JDBC`的分库分表通过规则配置描述,请简单浏览配置全貌:
+```java
+ ShardingRule shardingRule = new ShardingRule(
+ dataSourceRule,
+ Arrays.asList(tableRule),
+ new DatabaseShardingStrategy("sharding_column_1", new XXXShardingAlgorithm()),
+ new TableShardingStrategy("sharding_column_2", new XXXShardingAlgorithm()));
+```
+规则配置包括数据源配置、表规则配置、分库策略和分表策略组成。这只是最简单的配置方式,实际使用可更加灵活,如:多分片键,分片策略直接和`tableRule`绑定等。
+
+>详细的规则配置请参考[用户指南](post/user_guide)
+
+## 使用基于ShardingDataSource的JDBC接口
+通过规则配置对象获取`ShardingDataSource`,`ShardingDataSource`实现自`JDBC`的标准接口`DataSource`。然后可通过`DataSource`选择使用原生`JDBC`开发,或者使用`JPA`, `MyBatis`等`ORM`工具。
+以`JDBC`原生实现为例:
+```java
+DataSource dataSource = new ShardingDataSource(shardingRule);
+String sql = "SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.user_id=? AND o.order_id=?";
+try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement pstmt = conn.prepareStatement(sql)) {
+ pstmt.setInt(1, 10);
+ pstmt.setInt(2, 1001);
+ try (ResultSet rs = pstmt.executeQuery()) {
+ while(rs.next()) {
+ System.out.println(rs.getInt(1));
+ System.out.println(rs.getInt(2));
+ System.out.println(rs.getInt(3));
+ }
+ }
+}
+```
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000000000..76417a4f94844
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,650 @@
+
+ 4.0.0
+ com.dangdang
+ sharding-jdbc
+ 1.0.0
+ pom
+ ${project.artifactId}
+
+
+ sharding-jdbc-core
+
+
+
+ 1.7
+ [3.0.4,)
+ UTF-8
+ zh_CN
+
+ 1.16.4
+ 18.0
+ 2.6
+ 3.3.2
+ 4.1
+ 2.4
+ 1.6
+ 2.3
+ 2.3
+ 1.8.0
+ 3.1
+ 4.1.1.RELEASE
+ 3.2.8
+ 1.2.2
+ 2.1
+ 3.18.2-GA
+ 1.4
+ 0.9.1.2
+ 1.0.12
+ 0.9.3
+ 1.1.3
+ 1.1.2
+ 1.7.7
+ 3.1.0
+ 2.0
+ 2.4.5
+
+ 5.1.30
+ 1.4.184
+
+ 4.12
+ 2.5.0
+ 3.4.2
+ 1.2.1
+ 1.10.19
+
+ 3.3
+ 2.7
+ 2.6
+ 2.18.1
+ 3.4
+ 1.0.0
+ 1.4
+ 2.8
+ 3.4
+ 2.10.3
+ 2.4
+ 2.5
+ 2.7
+ 3.0.2
+ 2.16
+ 3.5
+ 2.0
+ 2.4
+ ${java.home}/../bin/javadoc
+
+
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+ commons-lang
+ commons-lang
+ ${commons-lang.version}
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+
+
+ org.apache.commons
+ commons-collections4
+ ${commons-collections4.version}
+
+
+ commons-io
+ commons-io
+ ${commons-io.version}
+
+
+ commons-pool
+ commons-pool
+ ${commons-pool.version}
+
+
+ org.apache.commons
+ commons-pool2
+ ${commons-pool2.version}
+
+
+ joda-time
+ joda-time
+ ${joda-time.version}
+
+
+ org.aspectj
+ aspectjweaver
+ ${aspectj.version}
+
+
+ cglib
+ cglib
+ ${cglib.version}
+
+
+ org.springframework
+ spring-context
+ ${springframework.version}
+
+
+ org.springframework
+ spring-core
+ ${springframework.version}
+
+
+ org.springframework
+ spring-beans
+ ${springframework.version}
+
+
+ org.springframework
+ spring-aspects
+ ${springframework.version}
+
+
+ org.springframework
+ spring-aop
+ ${springframework.version}
+
+
+ org.springframework
+ spring-jdbc
+ ${springframework.version}
+
+
+ org.springframework
+ spring-tx
+ ${springframework.version}
+
+
+ org.springframework
+ spring-context-support
+ ${springframework.version}
+
+
+ org.springframework
+ spring-web
+ ${springframework.version}
+
+
+ org.springframework
+ spring-webmvc
+ ${springframework.version}
+
+
+ org.springframework
+ spring-expression
+ ${springframework.version}
+
+
+ org.objenesis
+ objenesis
+ ${objenesis.version}
+
+
+ org.javassist
+ javassist
+ ${javassist.version}
+
+
+ org.mybatis
+ mybatis
+ ${mybatis.version}
+
+
+ org.mybatis
+ mybatis-spring
+ ${mybatis-spring.version}
+
+
+ commons-dbcp
+ commons-dbcp
+ ${commons-dbcp.version}
+
+
+ commons-pool
+ commons-pool
+
+
+
+
+ c3p0
+ c3p0
+ ${c3p0.version}
+
+
+ com.alibaba
+ druid
+ ${druid.version}
+
+
+ com.github.jsqlparser
+ jsqlparser
+ ${jsqlparser.version}
+
+
+ commons-logging
+ commons-logging
+ ${commons-logging.version}
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+ org.slf4j
+ jcl-over-slf4j
+ ${slf4j.version}
+
+
+ io.dropwizard.metrics
+ metrics-core
+ ${metrics.version}
+
+
+ com.jfinal
+ jfinal
+ ${jfinal.version}
+
+
+ org.codehaus.groovy
+ groovy
+ ${groovy.version}
+ indy
+
+
+
+ mysql
+ mysql-connector-java
+ ${mysql-connector-java.version}
+ runtime
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+ org.dbunit
+ dbunit
+ ${dbunit.version}
+ test
+
+
+ org.unitils
+ unitils-core
+ ${unitils.core.version}
+ test
+
+
+ commons-lang
+ commons-lang
+
+
+
+
+ org.springframework
+ spring-test
+ ${springframework.version}
+ test
+
+
+ com.github.springtestdbunit
+ spring-test-dbunit
+ ${spring-test-dbunit.version}
+ test
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+ com.h2database
+ h2
+ ${h2.version}
+ test
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ ${java.version}
+ ${java.version}
+ ${java.version}
+ ${java.version}
+
+ ${maven-compiler-plugin.version}
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ ${maven-resources-plugin.version}
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${maven-jar-plugin.version}
+
+
+ org.apache.maven.plugins
+ maven-surefire-report-plugin
+ ${maven-surefire-report-plugin.version}
+
+ once
+ -XX:-UseSplitVerifier
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ ${maven-site-plugin.version}
+
+ ${project.build.locale}
+
+
+
+ org.eclipse.m2e
+ lifecycle-mapping
+ ${lifecycle-mapping.version}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ [1.0.0,)
+
+ enforce
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-plugin-plugin
+ [1.0.0,)
+
+ descriptor
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-plugin-plugin
+ ${maven-plugin-plugin.version}
+
+ true
+
+
+
+ default-descriptor
+ process-classes
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ ${maven-javadoc-plugin.version}
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ ${maven-source-plugin.version}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ attach-sources
+ verify
+
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+ true
+ ${project.build.sourceEncoding}
+ ${project.build.sourceEncoding}
+ ${project.build.sourceEncoding}
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ ${maven-enforcer-plugin.version}
+
+
+ enforce-banned-dependencies
+
+ enforce
+
+
+
+
+ ${maven.version.range}
+
+
+ ${java.version}
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-project-info-reports-plugin
+ ${maven-project-info-reports-plugin.version}
+
+ false
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+ true
+ ${project.build.sourceEncoding}
+ ${project.build.sourceEncoding}
+ ${project.build.sourceEncoding}
+
+
+
+ org.apache.maven.plugins
+ maven-jxr-plugin
+ ${maven-jxr-plugin.version}
+
+ true
+
+
+
+ org.codehaus.mojo
+ cobertura-maven-plugin
+ ${cobertura-maven-plugin.version}
+
+ true
+ ${project.build.sourceEncoding}
+ true
+
+
+ com/dangdang/**/*Test.class
+ com/dangdang/**/Test*.class
+
+
+
+
+
+ org.codehaus.mojo
+ findbugs-maven-plugin
+ ${findbugs-maven-plugin.version}
+
+ true
+ Max
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ ${maven-checkstyle-plugin.version}
+
+ src/main/resources/dd_checks.xml
+
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+ ${maven-pmd-plugin.version}
+
+ true
+ true
+ ${project.build.sourceEncoding}
+ ${java.version}
+
+
+
+ org.codehaus.mojo
+ jdepend-maven-plugin
+ ${jdepend-maven-plugin.version}
+
+
+ org.codehaus.mojo
+ taglist-maven-plugin
+ ${taglist-maven-plugin.version}
+
+ true
+
+
+
+
+
+
+
+ henryyan-mavenrepo
+ https://maven.alfresco.com/nexus/content/groups/public/
+
+
+ java-net
+ https://oss.sonatype.org/content/repositories/snapshots/
+
+ false
+
+
+ false
+
+
+
+ terracotta-releases
+ http://terracotta.org/download/
+
+ false
+
+
+ false
+
+
+
+
+ http://www.dangdang.com
+ RDB Sharding
+
+
+ Apache Licene 2.0
+ http://www.apache.org/licenses/LICENSE-2.0.txt
+ repo
+
+
+
+
+ scm:https://github.com/dangdangdotcom/sharding-jdbc
+ scm:https://github.com/dangdangdotcom/sharding-jdbc
+ https://github.com/dangdangdotcom/sharding-jdbc
+
+
+
+
+ Zhangliang
+ zhangliang@dangdang.com
+
+
+
+
+
+ zhangliang
+ ZhangLiang
+ zhangliang@dangdang.com
+ 8
+
+
+
\ No newline at end of file
diff --git a/sharding-jdbc-core/pom.xml b/sharding-jdbc-core/pom.xml
new file mode 100644
index 0000000000000..4caaa00714b68
--- /dev/null
+++ b/sharding-jdbc-core/pom.xml
@@ -0,0 +1,82 @@
+
+ 4.0.0
+
+ com.dangdang
+ sharding-jdbc
+ 1.0.0
+
+ sharding-jdbc-core
+ ${project.artifactId}
+
+
+ org.projectlombok
+ lombok
+
+
+ com.google.guava
+ guava
+
+
+ org.apache.commons
+ commons-collections4
+
+
+
+ junit
+ junit
+
+
+ org.mockito
+ mockito-core
+
+
+ org.dbunit
+ dbunit
+
+
+ com.h2database
+ h2
+
+
+ commons-dbcp
+ commons-dbcp
+ test
+
+
+ commons-pool
+ commons-pool
+ test
+
+
+ mysql
+ mysql-connector-java
+
+
+ com.alibaba
+ druid
+
+
+ org.slf4j
+ slf4j-api
+
+
+ cglib
+ cglib
+
+
+ io.dropwizard.metrics
+ metrics-core
+
+
+ ch.qos.logback
+ logback-classic
+ test
+
+
+ org.slf4j
+ jcl-over-slf4j
+ test
+
+
+
\ No newline at end of file
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/DatabaseType.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/DatabaseType.java
new file mode 100644
index 0000000000000..2d0c3fe739ab6
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/DatabaseType.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api;
+
+import com.dangdang.ddframe.rdb.sharding.exception.DatabaseTypeUnsupportedException;
+
+/**
+ * 支持的数据库类型.
+ *
+ * @author zhangliang
+ */
+public enum DatabaseType {
+
+ H2, MySQL, Oracle, SQLServer, DB2;
+
+ /**
+ * 获取数据库类型枚举.
+ *
+ * @param databaseProductName 数据库类型
+ * @return 数据库类型枚举
+ */
+ public static DatabaseType valueFrom(final String databaseProductName) {
+ try {
+ return DatabaseType.valueOf(databaseProductName);
+ } catch (final IllegalArgumentException ex) {
+ throw new DatabaseTypeUnsupportedException(databaseProductName);
+ }
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/ShardingDataSource.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/ShardingDataSource.java
new file mode 100644
index 0000000000000..45ee1ba86ff74
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/ShardingDataSource.java
@@ -0,0 +1,94 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import com.dangdang.ddframe.rdb.sharding.api.config.ShardingConfiguration;
+import com.dangdang.ddframe.rdb.sharding.api.config.ShardingConfigurationConstant;
+import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
+import com.dangdang.ddframe.rdb.sharding.exception.ShardingJdbcException;
+import com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection;
+import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractDataSourceAdapter;
+import com.dangdang.ddframe.rdb.sharding.metrics.MetricsContext;
+import com.google.common.base.Preconditions;
+
+/**
+ * 支持分片的数据源.
+ *
+ * @author zhangliang
+ */
+public class ShardingDataSource extends AbstractDataSourceAdapter {
+
+ private final ShardingRule shardingRule;
+
+ private final DatabaseMetaData databaseMetaData;
+
+ private final ShardingConfiguration configuration;
+
+ private final MetricsContext metricsContext;
+
+ public ShardingDataSource(final ShardingRule shardingRule) {
+ this(shardingRule, new Properties());
+ }
+
+ public ShardingDataSource(final ShardingRule shardingRule, final Properties props) {
+ this.shardingRule = shardingRule;
+ databaseMetaData = getDatabaseMetaData();
+ configuration = new ShardingConfiguration(props);
+ metricsContext = new MetricsContext(configuration.getConfig(ShardingConfigurationConstant.METRICS_ENABLE, boolean.class),
+ configuration.getConfig(ShardingConfigurationConstant.METRICS_SECOND_PERIOD, long.class),
+ configuration.getConfig(ShardingConfigurationConstant.METRICS_PACKAGE_NAME, String.class));
+ }
+
+ private DatabaseMetaData getDatabaseMetaData() {
+ String databaseProductName = null;
+ DatabaseMetaData result = null;
+ for (DataSource each : shardingRule.getDataSourceRule().getDataSources()) {
+ String databaseProductNameInEach;
+ DatabaseMetaData metaDataInEach;
+ try {
+ metaDataInEach = each.getConnection().getMetaData();
+ databaseProductNameInEach = metaDataInEach.getDatabaseProductName();
+ } catch (final SQLException ex) {
+ throw new ShardingJdbcException("Can not get data source DatabaseProductName", ex);
+ }
+ Preconditions.checkState(null == databaseProductName || databaseProductName.equals(databaseProductNameInEach),
+ String.format("Database type inconsistent with '%s' and '%s'", databaseProductName, databaseProductNameInEach));
+ databaseProductName = databaseProductNameInEach;
+ result = metaDataInEach;
+ }
+ return result;
+ }
+
+ @Override
+ public ShardingConnection getConnection() throws SQLException {
+ metricsContext.register();
+ return new ShardingConnection(shardingRule, databaseMetaData);
+ }
+
+ @Override
+ public final Connection getConnection(final String username, final String password) throws SQLException {
+ return getConnection();
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/ShardingValue.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/ShardingValue.java
new file mode 100644
index 0000000000000..31647efab58b5
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/ShardingValue.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.ToString;
+
+import com.google.common.collect.Range;
+
+/**
+ * 分片值.
+ *
+ *
+ * 目前支持{@code =, IN, BETWEEN};
+ * 不支持{@code , >, <-, >=, LIKE, NOT, NOT IN}.
+ *
+ *
+ * @author zhangliang
+ */
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
+@Getter
+@ToString
+public final class ShardingValue> {
+
+ private final String columnName;
+
+ private final T value;
+
+ private final Collection values;
+
+ private final Range valueRange;
+
+ public ShardingValue(final String columnName, final T value) {
+ this(columnName, value, Collections.emptyList(), null);
+ }
+
+ public ShardingValue(final String columnName, final Collection values) {
+ this(columnName, null, values, null);
+ }
+
+ public ShardingValue(final String columnName, final Range valueRange) {
+ this(columnName, null, Collections.emptyList(), valueRange);
+ }
+
+ /**
+ * 获取分片值类型.
+ *
+ * @return 分片值类型
+ */
+ public ShardingValueType getType() {
+ if (null != value) {
+ return ShardingValueType.SINGLE;
+ }
+ if (!values.isEmpty()) {
+ return ShardingValueType.LIST;
+ }
+ return ShardingValueType.RANGE;
+ }
+
+ /**
+ * 分片值类型.
+ *
+ * @author zhangliang
+ */
+ public enum ShardingValueType {
+ SINGLE, LIST, RANGE
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/config/ShardingConfiguration.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/config/ShardingConfiguration.java
new file mode 100644
index 0000000000000..2d963d9e9e6bf
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/config/ShardingConfiguration.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.config;
+
+import java.util.Properties;
+
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 配置类.
+ *
+ * @author gaohongtao
+ */
+@RequiredArgsConstructor
+public final class ShardingConfiguration {
+
+ private final Properties props;
+
+ /**
+ * 获取字符串类型的配置.
+ *
+ * @param key 配置项的键值
+ * @return 配置值
+ */
+ public String getConfig(final ShardingConfigurationConstant key) {
+ return props.getProperty(key.getKey(), key.getDefaultValue());
+ }
+
+ /**
+ * 获取制定类型的配置.
+ *
+ * @param key 配置项的键值
+ * @param type 配置值的类型
+ * @return 配置值
+ */
+ public T getConfig(final ShardingConfigurationConstant key, final Class type) {
+ return convert(getConfig(key), type);
+ }
+
+ @SuppressWarnings("unchecked")
+ private T convert(final String value, final Class convertType) {
+ if (Boolean.class == convertType || boolean.class == convertType) {
+ return (T) Boolean.valueOf(value);
+ }
+ if (Integer.class == convertType || int.class == convertType) {
+ return (T) Integer.valueOf(value);
+ }
+ if (Long.class == convertType || long.class == convertType) {
+ return (T) Long.valueOf(value);
+ }
+ if (Double.class == convertType || double.class == convertType) {
+ return (T) Double.valueOf(value);
+ }
+ if (String.class == convertType) {
+ return (T) value;
+ }
+ throw new UnsupportedOperationException(String.format("unsupported config data type %s", convertType.getName()));
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/config/ShardingConfigurationConstant.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/config/ShardingConfigurationConstant.java
new file mode 100644
index 0000000000000..d037e8b7e4b3d
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/config/ShardingConfigurationConstant.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.config;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 配置项常量.
+ *
+ * @author gaohongtao
+ */
+@RequiredArgsConstructor
+@Getter
+public enum ShardingConfigurationConstant {
+
+ /**
+ * 度量输出周期.
+ * 单位为秒
+ * 默认值:30秒
+ */
+ METRICS_SECOND_PERIOD("metrics.second.period", "1"),
+
+ /**
+ * 是否开启度量采集.
+ * 默认值: 不开启
+ */
+ METRICS_ENABLE("metrics.enable", Boolean.FALSE.toString()),
+
+ /**
+ * 度量输出在日志中的标识名称.
+ */
+ METRICS_PACKAGE_NAME("metrics.package.name", "com.dangdang.ddframe.rdb.sharding.metrics");
+
+ private final String key;
+
+ private final String defaultValue;
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/BindingTableRule.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/BindingTableRule.java
new file mode 100644
index 0000000000000..57ba649be0cc7
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/BindingTableRule.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.rule;
+
+import java.util.Collection;
+import java.util.List;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * Binding表规则配置对象.
+ *
+ * @author zhangliang
+ */
+@RequiredArgsConstructor
+@Getter
+public final class BindingTableRule {
+
+ private final List tableRules;
+
+ /**
+ * 判断此绑定表规则是否包含该逻辑表.
+ *
+ * @param logicTableName 逻辑表名称
+ * @return 此绑定表规则是否包含该逻辑表
+ */
+ public boolean hasLogicTable(final String logicTableName) {
+ for (TableRule each : tableRules) {
+ if (each.getLogicTable().equals(logicTableName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 根据其他Binding表真实表名称获取相应的真实Binding表名称.
+ *
+ * @param dataSource 数据源名称
+ * @param logicTable 逻辑表名称
+ * @param otherActualTable 其他真实Binding表名称
+ * @return 真实Binding表名称
+ */
+ public String getBindingActualTable(final String dataSource, final String logicTable, final String otherActualTable) {
+ int index = -1;
+ for (TableRule each : tableRules) {
+ index = each.findActualTableIndex(dataSource, otherActualTable);
+ if (-1 != index) {
+ break;
+ }
+ }
+ Preconditions.checkState(-1 != index, String.format("Actual table [%s].[%s] is not in table config", dataSource, otherActualTable));
+ for (TableRule each : tableRules) {
+ if (each.getLogicTable().equals(logicTable)) {
+ return each.getActualTables().get(index).getTableName();
+ }
+ }
+ throw new IllegalStateException(String.format("Cannot find binding actual table, data source: %s, logic table: %s, other actual table: %s", dataSource, logicTable, otherActualTable));
+ }
+
+ Collection getAllLogicTables() {
+ return Lists.transform(tableRules, new Function() {
+
+ @Override
+ public String apply(final TableRule input) {
+ return input.getLogicTable();
+ }
+ });
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataNode.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataNode.java
new file mode 100644
index 0000000000000..187639a2dad03
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataNode.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.rule;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 分库分表数据单元.
+ *
+ * @author zhangliang
+ */
+@RequiredArgsConstructor
+@Getter
+@EqualsAndHashCode
+@ToString
+public final class DataNode {
+
+ private final String dataSourceName;
+
+ private final String tableName;
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataSourceRule.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataSourceRule.java
new file mode 100644
index 0000000000000..9064f36f13beb
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataSourceRule.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.rule;
+
+import java.util.Collection;
+import java.util.Map;
+
+import javax.sql.DataSource;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * 数据源配置对象.
+ *
+ * @author zhangliang
+ */
+public final class DataSourceRule {
+
+ private final Map dataSourceMap;
+
+ public DataSourceRule(final Map dataSourceMap) {
+ Preconditions.checkNotNull(dataSourceMap, "Must have one data source at least.");
+ Preconditions.checkState(!dataSourceMap.isEmpty(), "Must have one data source at least.");
+ this.dataSourceMap = dataSourceMap;
+ }
+
+ /**
+ * 获取数据源实例.
+ *
+ * @param name 数据源名称
+ * @return 数据源实例
+ */
+ public DataSource getDataSource(final String name) {
+ return dataSourceMap.get(name);
+ }
+
+ /**
+ * 获取所有数据源名称.
+ *
+ * @return 所有数据源名称
+ */
+ public Collection getDataSourceNames() {
+ return dataSourceMap.keySet();
+ }
+
+ /**
+ * 获取所有数据源.
+ *
+ * @return 所有数据源
+ */
+ public Collection getDataSources() {
+ return dataSourceMap.values();
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/ShardingRule.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/ShardingRule.java
new file mode 100644
index 0000000000000..50c3c6270317d
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/ShardingRule.java
@@ -0,0 +1,213 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.rule;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy;
+import com.dangdang.ddframe.rdb.sharding.api.strategy.database.NoneDatabaseShardingAlgorithm;
+import com.dangdang.ddframe.rdb.sharding.api.strategy.table.NoneTableShardingAlgorithm;
+import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 分库分表规则配置对象.
+ *
+ * @author zhangliang
+ */
+@AllArgsConstructor
+@Getter
+public final class ShardingRule {
+
+ private final DataSourceRule dataSourceRule;
+
+ private final Collection tableRules;
+
+ private Collection bindingTableRules;
+
+ private DatabaseShardingStrategy databaseShardingStrategy;
+
+ private TableShardingStrategy tableShardingStrategy;
+
+ public ShardingRule(final DataSourceRule dataSourceRule, final Collection tableRules) {
+ this(dataSourceRule, tableRules, Collections.emptyList(),
+ new DatabaseShardingStrategy(Collections.emptyList(), new NoneDatabaseShardingAlgorithm()),
+ new TableShardingStrategy(Collections.emptyList(), new NoneTableShardingAlgorithm()));
+ }
+
+ public ShardingRule(final DataSourceRule dataSourceRule, final Collection tableRules, final Collection bindingTableRules) {
+ this(dataSourceRule, tableRules, bindingTableRules,
+ new DatabaseShardingStrategy(Collections.emptyList(), new NoneDatabaseShardingAlgorithm()),
+ new TableShardingStrategy(Collections.emptyList(), new NoneTableShardingAlgorithm()));
+ }
+
+ public ShardingRule(final DataSourceRule dataSourceRule, final Collection tableRules, final DatabaseShardingStrategy databaseShardingStrategy) {
+ this(dataSourceRule, tableRules, Collections.emptyList(),
+ databaseShardingStrategy, new TableShardingStrategy(Collections.emptyList(), new NoneTableShardingAlgorithm()));
+ }
+
+ public ShardingRule(final DataSourceRule dataSourceRule, final Collection tableRules, final TableShardingStrategy tableShardingStrategy) {
+ this(dataSourceRule, tableRules, Collections.emptyList(),
+ new DatabaseShardingStrategy(Collections.emptyList(), new NoneDatabaseShardingAlgorithm()), tableShardingStrategy);
+ }
+
+ public ShardingRule(final DataSourceRule dataSourceRule, final Collection tableRules,
+ final DatabaseShardingStrategy databaseShardingStrategy, final TableShardingStrategy tableShardingStrategy) {
+ this(dataSourceRule, tableRules, Collections.emptyList(), databaseShardingStrategy, tableShardingStrategy);
+ }
+
+ /**
+ * 根据逻辑表名称查找分片规则.
+ *
+ * @param logicTableName 逻辑表名称
+ * @return 该逻辑表的分片规则
+ */
+ public Optional findTableRule(final String logicTableName) {
+ for (TableRule each : tableRules) {
+ if (each.getLogicTable().equals(logicTableName)) {
+ return Optional.of(each);
+ }
+ }
+ return Optional.absent();
+ }
+
+ /**
+ * 获取数据库分片策略.
+ *
+ *
+ * 根据表规则配置对象获取分片策略, 如果获取不到则获取默认分片策略.
+ *
+ *
+ * @param tableRule 表规则配置对象
+ * @return 数据库分片策略
+ */
+ public DatabaseShardingStrategy getDatabaseShardingStrategy(final TableRule tableRule) {
+ DatabaseShardingStrategy result = tableRule.getDatabaseShardingStrategy();
+ if (null == result) {
+ result = databaseShardingStrategy;
+ }
+ Preconditions.checkNotNull(result, "no database sharding strategy");
+ return result;
+ }
+
+ /**
+ * 获取表分片策略.
+ *
+ *
+ * 根据表规则配置对象获取分片策略, 如果获取不到则获取默认分片策略.
+ *
+ *
+ * @param tableRule 表规则配置对象
+ * @return 表分片策略
+ */
+ public TableShardingStrategy getTableShardingStrategy(final TableRule tableRule) {
+ TableShardingStrategy result = tableRule.getTableShardingStrategy();
+ if (null == result) {
+ result = tableShardingStrategy;
+ }
+ Preconditions.checkNotNull(result, "no table sharding strategy");
+ return result;
+ }
+
+ /**
+ * 根据逻辑表名称获取binding表配置的逻辑表名称集合.
+ *
+ * @param logicTable 逻辑表名称
+ * @return binding表配置的逻辑表名称集合
+ */
+ public Optional getBindingTableRule(final String logicTable) {
+ if (null == bindingTableRules) {
+ return Optional.absent();
+ }
+ for (BindingTableRule each : bindingTableRules) {
+ if (each.hasLogicTable(logicTable)) {
+ return Optional.of(each);
+ }
+ }
+ return Optional.absent();
+ }
+
+ /**
+ * 过滤出所有的Binding表名称.
+ *
+ * @param logicTables 逻辑表名称集合
+ * @return 所有的Binding表名称集合
+ */
+ public Collection filterAllBindingTables(final Collection logicTables) {
+ if (logicTables.isEmpty()) {
+ return Collections.emptyList();
+ }
+ Optional bindingTableRule = Optional.absent();
+ for (String each : logicTables) {
+ bindingTableRule = getBindingTableRule(each);
+ if (bindingTableRule.isPresent()) {
+ break;
+ }
+ }
+ if (!bindingTableRule.isPresent()) {
+ return Collections.emptyList();
+ }
+ Collection result = new ArrayList<>(bindingTableRule.get().getAllLogicTables());
+ result.retainAll(logicTables);
+ return result;
+ }
+
+ /**
+ * 判断逻辑表名称集合是否全部属于Binding表.
+ *
+ * @param logicTables 逻辑表名称集合
+ * @return 是否全部属于Binding表
+ */
+ public boolean isAllBindingTable(final Collection logicTables) {
+ Collection bindingTables = filterAllBindingTables(logicTables);
+ return !bindingTables.isEmpty() && bindingTables.containsAll(logicTables);
+ }
+
+ /**
+ * 获取所有的分片列名.
+ *
+ * @return 分片列名集合
+ */
+ // TODO 目前使用分片列名称, 为了进一步提升解析性能,应考虑使用表名 + 列名
+ public Collection getAllShardingColumns() {
+ Set result = new HashSet<>();
+ if (null != databaseShardingStrategy) {
+ result.addAll(databaseShardingStrategy.getShardingColumns());
+ }
+ if (null != tableShardingStrategy) {
+ result.addAll(tableShardingStrategy.getShardingColumns());
+ }
+ for (TableRule each : tableRules) {
+ if (null != each.getDatabaseShardingStrategy()) {
+ result.addAll(each.getDatabaseShardingStrategy().getShardingColumns());
+ }
+ if (null != each.getTableShardingStrategy()) {
+ result.addAll(each.getTableShardingStrategy().getShardingColumns());
+ }
+ }
+ return result;
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/TableRule.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/TableRule.java
new file mode 100644
index 0000000000000..32d9611d3ffe5
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/TableRule.java
@@ -0,0 +1,134 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.rule;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy;
+import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy;
+import com.google.common.base.Splitter;
+
+/**
+ * 表规则配置对象.
+ *
+ * @author zhangliang
+ */
+@AllArgsConstructor
+@RequiredArgsConstructor
+@Getter
+@ToString
+public final class TableRule {
+
+ private final String logicTable;
+
+ private final List actualTables;
+
+ private DatabaseShardingStrategy databaseShardingStrategy;
+
+ private TableShardingStrategy tableShardingStrategy;
+
+ public TableRule(final String logicTable, final List actualTables, final DataSourceRule dataSourceRule,
+ final DatabaseShardingStrategy databaseShardingStrategy, final TableShardingStrategy tableShardingStrategy) {
+ this(logicTable, new ArrayList(actualTables.size() * dataSourceRule.getDataSourceNames().size()), databaseShardingStrategy, tableShardingStrategy);
+ generateDataNodes(actualTables, dataSourceRule);
+ }
+
+ public TableRule(final String logicTable, final List actualTables, final DataSourceRule dataSourceRule) {
+ this(logicTable, actualTables, dataSourceRule, null, null);
+ }
+
+ public TableRule(final String logicTable, final List actualTables, final DataSourceRule dataSourceRule, final DatabaseShardingStrategy databaseShardingStrategy) {
+ this(logicTable, actualTables, dataSourceRule, databaseShardingStrategy, null);
+ }
+
+ public TableRule(final String logicTable, final List actualTables, final DataSourceRule dataSourceRule, final TableShardingStrategy tableShardingStrategy) {
+ this(logicTable, actualTables, dataSourceRule, null, tableShardingStrategy);
+ }
+
+ private void generateDataNodes(final List actualTables, final DataSourceRule dataSourceRule) {
+ for (String actualTable : actualTables) {
+ if (actualTable.contains(".")) {
+ List actualDatabaseTable = Splitter.on(".").splitToList(actualTable);
+ this.actualTables.add(new DataNode(actualDatabaseTable.get(0), actualDatabaseTable.get(1)));
+ } else {
+ for (String dataSourceName : dataSourceRule.getDataSourceNames()) {
+ this.actualTables.add(new DataNode(dataSourceName, actualTable));
+ }
+ }
+ }
+ }
+
+ /**
+ * 根据数据源名称过滤获取真实数据单元.
+ *
+ * @param targetDataSources 数据源名称集合
+ * @param targetTables 真实表名称集合
+ * @return 真实数据单元
+ */
+ public Collection getActualDataNodes(final Collection targetDataSources, final Collection targetTables) {
+ Collection result = new LinkedHashSet<>(actualTables.size());
+ for (DataNode each : actualTables) {
+ if (targetDataSources.contains(each.getDataSourceName()) && targetTables.contains(each.getTableName())) {
+ result.add(each);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * 根据数据源名称过滤获取真实表名称.
+ *
+ * @param targetDataSources 数据源名称
+ * @return 真实表名称
+ */
+ public Collection getActualTableNames(final Collection targetDataSources) {
+ Collection result = new LinkedHashSet<>(actualTables.size());
+ for (DataNode each : actualTables) {
+ if (targetDataSources.contains(each.getDataSourceName())) {
+ result.add(each.getTableName());
+ }
+ }
+ return result;
+ }
+
+ /**
+ * 根据数据源和真实表名称查找真实表顺序.
+ *
+ * @param dataSourceName 数据源名称
+ * @param actualTableName 真实表名称
+ * @return 真实表顺序
+ */
+ public int findActualTableIndex(final String dataSourceName, final String actualTableName) {
+ int result = 0;
+ for (DataNode each : actualTables) {
+ if (each.getDataSourceName().equals(dataSourceName) && each.getTableName().equals(actualTableName)) {
+ return result;
+ }
+ result++;
+ }
+ return -1;
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/MultipleKeysShardingAlgorithm.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/MultipleKeysShardingAlgorithm.java
new file mode 100644
index 0000000000000..eeed9b410330c
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/MultipleKeysShardingAlgorithm.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.common;
+
+import java.util.Collection;
+
+import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
+
+/**
+ * 多片键分片法接口.
+ *
+ * @author zhangliang
+ */
+public interface MultipleKeysShardingAlgorithm extends ShardingAlgorithm {
+
+ /**
+ * 根据分片值计算分片结果名称集合.
+ *
+ * @param availableTargetNames 所有的可用目标名称集合, 一般是数据源或表名称
+ * @param shardingValues 分片值集合
+ * @return 分片后指向的目标名称集合, 一般是数据源或表名称
+ */
+ Collection doSharding(Collection availableTargetNames, Collection> shardingValues);
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingAlgorithm.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingAlgorithm.java
new file mode 100644
index 0000000000000..f8402baa26d6f
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingAlgorithm.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.common;
+
+/**
+ * 分片算法的标识接口.
+ *
+ * @author zhangliang
+ */
+public interface ShardingAlgorithm {
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingStrategy.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingStrategy.java
new file mode 100644
index 0000000000000..970877f3b8a8d
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/ShardingStrategy.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.common;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
+
+/**
+ * 分片策略.
+ *
+ * @author zhangliang
+ */
+@RequiredArgsConstructor
+public class ShardingStrategy {
+
+ @Getter
+ private final Collection shardingColumns;
+
+ private final ShardingAlgorithm shardingAlgorithm;
+
+ public ShardingStrategy(final String shardingColumn, final ShardingAlgorithm shardingAlgorithm) {
+ this(Arrays.asList(shardingColumn), shardingAlgorithm);
+ }
+
+ /**
+ * 根据分片值计算数据源名称集合.
+ *
+ * @param availableTargetNames 所有的可用数据源名称集合
+ * @param shardingValues 分库片值集合
+ * @return 分库后指向的数据源名称集合
+ */
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public Collection doSharding(final Collection availableTargetNames, final Collection>> shardingValues) {
+ if (shardingValues.isEmpty()) {
+ return availableTargetNames;
+ }
+ if (shardingAlgorithm instanceof SingleKeyShardingAlgorithm) {
+ SingleKeyShardingAlgorithm> singleKeyShardingAlgorithm = (SingleKeyShardingAlgorithm>) shardingAlgorithm;
+ ShardingValue shardingValue = shardingValues.iterator().next();
+ switch (shardingValue.getType()) {
+ case SINGLE:
+ return Arrays.asList(singleKeyShardingAlgorithm.doEqualSharding(availableTargetNames, shardingValue));
+ case LIST:
+ return singleKeyShardingAlgorithm.doInSharding(availableTargetNames, shardingValue);
+ case RANGE:
+ return singleKeyShardingAlgorithm.doBetweenSharding(availableTargetNames, shardingValue);
+ default:
+ throw new UnsupportedOperationException(shardingValue.getType().getClass().getName());
+ }
+ }
+ if (shardingAlgorithm instanceof MultipleKeysShardingAlgorithm) {
+ return ((MultipleKeysShardingAlgorithm) shardingAlgorithm).doSharding(availableTargetNames, shardingValues);
+ }
+ throw new UnsupportedOperationException(shardingAlgorithm.getClass().getName());
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/SingleKeyShardingAlgorithm.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/SingleKeyShardingAlgorithm.java
new file mode 100644
index 0000000000000..0f0efacf9f47b
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/common/SingleKeyShardingAlgorithm.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.common;
+
+import java.util.Collection;
+
+import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
+
+/**
+ * 单片键分片法接口.
+ *
+ * @author zhangliang
+ *
+ * @param 片键类型
+ */
+public interface SingleKeyShardingAlgorithm> extends ShardingAlgorithm {
+
+ /**
+ * 根据分片值和SQL的=运算符计算分片结果名称集合.
+ *
+ * @param availableTargetNames 所有的可用目标名称集合, 一般是数据源或表名称
+ * @param shardingValue 分片值
+ * @return 分片后指向的目标名称, 一般是数据源或表名称
+ */
+ String doEqualSharding(Collection availableTargetNames, ShardingValue shardingValue);
+
+ /**
+ * 根据分片值和SQL的IN运算符计算分片结果名称集合.
+ *
+ * @param availableTargetNames 所有的可用目标名称集合, 一般是数据源或表名称
+ * @param shardingValue 分片值
+ * @return 分片后指向的目标名称集合, 一般是数据源或表名称
+ */
+ Collection doInSharding(Collection availableTargetNames, ShardingValue shardingValue);
+
+ /**
+ * 根据分片值和SQL的BETWEEN运算符计算分片结果名称集合.
+ *
+ * @param availableTargetNames 所有的可用目标名称集合, 一般是数据源或表名称
+ * @param shardingValue 分片值
+ * @return 分片后指向的目标名称集合, 一般是数据源或表名称
+ */
+ Collection doBetweenSharding(Collection availableTargetNames, ShardingValue shardingValue);
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/DatabaseShardingAlgorithm.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/DatabaseShardingAlgorithm.java
new file mode 100644
index 0000000000000..3e0a28f0f882f
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/DatabaseShardingAlgorithm.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.database;
+
+import com.dangdang.ddframe.rdb.sharding.api.strategy.common.ShardingAlgorithm;
+
+/**
+ * 分库算法接口.
+ *
+ * @author zhangliang
+ */
+public interface DatabaseShardingAlgorithm extends ShardingAlgorithm {
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/DatabaseShardingStrategy.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/DatabaseShardingStrategy.java
new file mode 100644
index 0000000000000..687610b923c4e
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/DatabaseShardingStrategy.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.database;
+
+import java.util.Collection;
+
+import com.dangdang.ddframe.rdb.sharding.api.strategy.common.ShardingStrategy;
+
+/**
+ * 分库策略.
+ *
+ * @author zhangliang
+ */
+public final class DatabaseShardingStrategy extends ShardingStrategy {
+
+ public DatabaseShardingStrategy(final String shardingColumn, final SingleKeyDatabaseShardingAlgorithm> databaseShardingAlgorithm) {
+ super(shardingColumn, databaseShardingAlgorithm);
+ }
+
+ public DatabaseShardingStrategy(final Collection shardingColumns, final MultipleKeysDatabaseShardingAlgorithm databaseShardingAlgorithm) {
+ super(shardingColumns, databaseShardingAlgorithm);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/MultipleKeysDatabaseShardingAlgorithm.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/MultipleKeysDatabaseShardingAlgorithm.java
new file mode 100644
index 0000000000000..3e32a715cd28a
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/MultipleKeysDatabaseShardingAlgorithm.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.database;
+
+import com.dangdang.ddframe.rdb.sharding.api.strategy.common.MultipleKeysShardingAlgorithm;
+
+/**
+ * 多片键分库算法接口.
+ *
+ * @author zhangliang
+ */
+public interface MultipleKeysDatabaseShardingAlgorithm extends MultipleKeysShardingAlgorithm, DatabaseShardingAlgorithm {
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/NoneDatabaseShardingAlgorithm.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/NoneDatabaseShardingAlgorithm.java
new file mode 100644
index 0000000000000..44cd0472dfff8
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/NoneDatabaseShardingAlgorithm.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.database;
+
+import java.util.Collection;
+
+import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
+
+/**
+ * 无需分库的分片算法.
+ *
+ * @author zhangliang
+ */
+public final class NoneDatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm, MultipleKeysDatabaseShardingAlgorithm {
+
+ @Override
+ public Collection doSharding(final Collection availableTargetNames, final Collection> shardingValues) {
+ return availableTargetNames;
+ }
+
+ @Override
+ public String doEqualSharding(final Collection availableTargetNames, final ShardingValue shardingValue) {
+ return availableTargetNames.isEmpty() ? null : availableTargetNames.iterator().next();
+ }
+
+ @Override
+ public Collection doInSharding(final Collection availableTargetNames, final ShardingValue shardingValue) {
+ return availableTargetNames;
+ }
+
+ @Override
+ public Collection doBetweenSharding(final Collection availableTargetNames, final ShardingValue shardingValue) {
+ return availableTargetNames;
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/SingleKeyDatabaseShardingAlgorithm.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/SingleKeyDatabaseShardingAlgorithm.java
new file mode 100644
index 0000000000000..40b65195b5cc0
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/database/SingleKeyDatabaseShardingAlgorithm.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.database;
+
+import com.dangdang.ddframe.rdb.sharding.api.strategy.common.SingleKeyShardingAlgorithm;
+
+/**
+ * 单分片键的分库算法接口.
+ *
+ * @author zhangliang
+ */
+public interface SingleKeyDatabaseShardingAlgorithm> extends SingleKeyShardingAlgorithm, DatabaseShardingAlgorithm {
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/MultipleKeysTableShardingAlgorithm.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/MultipleKeysTableShardingAlgorithm.java
new file mode 100644
index 0000000000000..207964265ee73
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/MultipleKeysTableShardingAlgorithm.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.table;
+
+import com.dangdang.ddframe.rdb.sharding.api.strategy.common.MultipleKeysShardingAlgorithm;
+
+/**
+ * 多片键分表算法接口.
+ *
+ * @author zhangliang
+ */
+public interface MultipleKeysTableShardingAlgorithm extends MultipleKeysShardingAlgorithm, TableShardingAlgorithm {
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/NoneTableShardingAlgorithm.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/NoneTableShardingAlgorithm.java
new file mode 100644
index 0000000000000..a279d895d2332
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/NoneTableShardingAlgorithm.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.table;
+
+import java.util.Collection;
+
+import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
+
+/**
+ * 无需分表的分片算法.
+ *
+ * @author zhangliang
+ */
+public final class NoneTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm, MultipleKeysTableShardingAlgorithm {
+
+ @Override
+ public Collection doSharding(final Collection availableTableNames, final Collection> shardingValues) {
+ return availableTableNames;
+ }
+
+ @Override
+ public String doEqualSharding(final Collection availableTargetNames, final ShardingValue shardingValue) {
+ return availableTargetNames.isEmpty() ? null : availableTargetNames.iterator().next();
+ }
+
+ @Override
+ public Collection doInSharding(final Collection availableTargetNames, final ShardingValue shardingValue) {
+ return availableTargetNames;
+ }
+
+ @Override
+ public Collection doBetweenSharding(final Collection availableTargetNames, final ShardingValue shardingValue) {
+ return availableTargetNames;
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/SingleKeyTableShardingAlgorithm.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/SingleKeyTableShardingAlgorithm.java
new file mode 100644
index 0000000000000..5eb5ce5c26cb9
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/SingleKeyTableShardingAlgorithm.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.table;
+
+import com.dangdang.ddframe.rdb.sharding.api.strategy.common.SingleKeyShardingAlgorithm;
+
+/**
+ * 单分片键的分表算法接口.
+ *
+ * @author zhangliang
+ */
+public interface SingleKeyTableShardingAlgorithm> extends SingleKeyShardingAlgorithm, TableShardingAlgorithm {
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/TableShardingAlgorithm.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/TableShardingAlgorithm.java
new file mode 100644
index 0000000000000..25da6aed6f3dd
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/TableShardingAlgorithm.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.table;
+
+import com.dangdang.ddframe.rdb.sharding.api.strategy.common.ShardingAlgorithm;
+
+/**
+ * 分表算法接口.
+ *
+ * @author zhangliang
+ */
+public interface TableShardingAlgorithm extends ShardingAlgorithm {
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/TableShardingStrategy.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/TableShardingStrategy.java
new file mode 100644
index 0000000000000..195ff34c18bb6
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/table/TableShardingStrategy.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.api.strategy.table;
+
+import java.util.Collection;
+
+import com.dangdang.ddframe.rdb.sharding.api.strategy.common.ShardingStrategy;
+
+/**
+ * 分表策略.
+ *
+ * @author zhangliang
+ */
+public final class TableShardingStrategy extends ShardingStrategy {
+
+ public TableShardingStrategy(final String shardingColumn, final SingleKeyTableShardingAlgorithm> tableShardingAlgorithm) {
+ super(shardingColumn, tableShardingAlgorithm);
+ }
+
+ public TableShardingStrategy(final Collection shardingColumns, final MultipleKeysTableShardingAlgorithm tableShardingAlgorithm) {
+ super(shardingColumns, tableShardingAlgorithm);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/exception/DatabaseTypeUnsupportedException.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/exception/DatabaseTypeUnsupportedException.java
new file mode 100644
index 0000000000000..0c8f370491539
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/exception/DatabaseTypeUnsupportedException.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.exception;
+
+/**
+ * 不支持的数据库抛出的异常.
+ *
+ * @author zhangliang
+ */
+public class DatabaseTypeUnsupportedException extends RuntimeException {
+
+ private static final long serialVersionUID = -7807395469148925091L;
+
+ private static final String MESSAGE = "Can not support database type [%s].";
+
+ public DatabaseTypeUnsupportedException(final String databaseType) {
+ super(String.format(MESSAGE, databaseType));
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/exception/SQLParserException.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/exception/SQLParserException.java
new file mode 100644
index 0000000000000..21053e8068860
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/exception/SQLParserException.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.exception;
+
+/**
+ * SQL解析异常.
+ *
+ * @author gaohongtao
+ */
+public final class SQLParserException extends ShardingJdbcException {
+
+ private static final long serialVersionUID = -1498980479829506655L;
+
+ public SQLParserException(final String message, final Object... args) {
+ super(String.format(message, args));
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/exception/ShardingJdbcException.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/exception/ShardingJdbcException.java
new file mode 100644
index 0000000000000..a3ad81b16c74c
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/exception/ShardingJdbcException.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.exception;
+
+/**
+ * JDBC分片抛出的异常基类.
+ *
+ * @author zhangliang
+ */
+public class ShardingJdbcException extends RuntimeException {
+
+ private static final long serialVersionUID = -1343739516839252250L;
+
+ public ShardingJdbcException(final String errorMessage, final Object... args) {
+ super(String.format(errorMessage, args));
+ }
+
+ public ShardingJdbcException(final Exception cause) {
+ super(cause);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/ExecuteUnit.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/ExecuteUnit.java
new file mode 100644
index 0000000000000..70a9e4472f180
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/ExecuteUnit.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.executor;
+
+/**
+ * 执行单元.
+ *
+ * @author gaohongtao
+ */
+public interface ExecuteUnit {
+
+ /**
+ * 执行任务.
+ *
+ * @param input 输入待处理数据
+ * @return 返回处理结果
+ * @throws Exception 执行期异常
+ */
+ O execute(I input) throws Exception;
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/ExecutorEngine.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/ExecutorEngine.java
new file mode 100644
index 0000000000000..1defea8912904
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/ExecutorEngine.java
@@ -0,0 +1,116 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.executor;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+
+import com.dangdang.ddframe.rdb.sharding.exception.ShardingJdbcException;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 多线程执行框架.
+ *
+ * @author gaohongtao
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+@Slf4j
+public final class ExecutorEngine {
+
+ /**
+ * 多线程执行任务.
+ *
+ * @param inputs 输入参数
+ * @param executeUnit 执行单元
+ * @param 入参类型
+ * @param 出参类型
+ * @return 执行结果
+ */
+ public static List execute(final Collection inputs, final ExecuteUnit executeUnit) {
+ ListenableFuture> futures = submitFutures(inputs, executeUnit);
+ addCallback(futures);
+ return getFutureResults(futures);
+ }
+
+ /**
+ * 多线程执行任务并归并结果.
+ *
+ * @param inputs 执行入参
+ * @param executeUnit 执行单元
+ * @param mergeUnit 合并结果单元
+ * @param 入参类型
+ * @param 中间结果类型
+ * @param 最终结果类型
+ * @return 执行结果
+ */
+ public static O execute(final Collection inputs, final ExecuteUnit executeUnit, final MergeUnit mergeUnit) {
+ return mergeUnit.merge(execute(inputs, executeUnit));
+ }
+
+ private static ListenableFuture> submitFutures(final Collection inputs, final ExecuteUnit executeUnit) {
+ Set> result = new HashSet<>(inputs.size());
+ ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(inputs.size()));
+ for (final I each : inputs) {
+ result.add(service.submit(new Callable() {
+
+ @Override
+ public O call() throws Exception {
+ return executeUnit.execute(each);
+ }
+ }));
+ }
+ service.shutdown();
+ return Futures.allAsList(result);
+ }
+
+ private static void addCallback(final ListenableFuture allFutures) {
+ Futures.addCallback(allFutures, new FutureCallback() {
+
+ @Override
+ public void onSuccess(final T result) {
+ log.trace("Concurrent execute result success {}", result);
+ }
+
+ @Override
+ public void onFailure(final Throwable thrown) {
+ log.error("Concurrent execute result error {}", thrown);
+ }
+ });
+ }
+
+ private static O getFutureResults(final ListenableFuture futures) {
+ try {
+ return futures.get();
+ } catch (final InterruptedException | ExecutionException ex) {
+ throw new ShardingJdbcException(ex);
+ }
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/MergeUnit.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/MergeUnit.java
new file mode 100644
index 0000000000000..3f36e264e48ce
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/MergeUnit.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.executor;
+
+import java.util.List;
+
+/**
+ * 合并执行单元.
+ *
+ * @author gaohongtao
+ */
+public interface MergeUnit {
+
+ /**
+ * 合并执行结果.
+ *
+ * @param params 合并前数据
+ * @return 合并后结果
+ */
+ O merge(final List params);
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/PreparedStatementExecutor.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/PreparedStatementExecutor.java
new file mode 100644
index 0000000000000..52ed3dce08c8f
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/PreparedStatementExecutor.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.executor;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import com.codahale.metrics.Timer.Context;
+import com.dangdang.ddframe.rdb.sharding.metrics.MetricsContext;
+
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 多线程执行预编译语句对象请求的执行器.
+ *
+ * @author zhangliang
+ */
+@RequiredArgsConstructor
+public final class PreparedStatementExecutor {
+
+ private final Collection preparedStatements;
+
+ /**
+ * 执行SQL查询.
+ *
+ * @return 结果集列表
+ * @throws SQLException SQL异常
+ */
+ public List executeQuery() throws SQLException {
+ Context context = MetricsContext.start("ShardingPreparedStatement-executeQuery");
+ List result;
+ if (1 == preparedStatements.size()) {
+ result = Arrays.asList(preparedStatements.iterator().next().executeQuery());
+ MetricsContext.stop(context);
+ return result;
+ }
+ result = ExecutorEngine.execute(preparedStatements, new ExecuteUnit() {
+
+ @Override
+ public ResultSet execute(final PreparedStatement input) throws Exception {
+ return input.executeQuery();
+ }
+ });
+ MetricsContext.stop(context);
+ return result;
+ }
+
+ /**
+ * 执行SQL更新.
+ *
+ * @return 更新数量
+ * @throws SQLException SQL异常
+ */
+ public int executeUpdate() throws SQLException {
+ Context context = MetricsContext.start("ShardingPreparedStatement-executeUpdate");
+ int result;
+ if (1 == preparedStatements.size()) {
+ result = preparedStatements.iterator().next().executeUpdate();
+ MetricsContext.stop(context);
+ return result;
+ }
+ result = ExecutorEngine.execute(preparedStatements, new ExecuteUnit() {
+
+ @Override
+ public Integer execute(final PreparedStatement input) throws Exception {
+ return input.executeUpdate();
+ }
+ }, new MergeUnit() {
+
+ @Override
+ public Integer merge(final List results) {
+ int result = 0;
+ for (Integer each : results) {
+ result += each;
+ }
+ return result;
+ }
+ });
+ MetricsContext.stop(context);
+ return result;
+ }
+
+ /**
+ * 执行SQL请求.
+ *
+ * @return true表示执行DQL, false表示执行的DML
+ * @throws SQLException SQL异常
+ */
+ public boolean execute() throws SQLException {
+ Context context = MetricsContext.start("ShardingPreparedStatement-execute");
+ if (1 == preparedStatements.size()) {
+ boolean result = preparedStatements.iterator().next().execute();
+ MetricsContext.stop(context);
+ return result;
+ }
+ List result = ExecutorEngine.execute(preparedStatements, new ExecuteUnit() {
+
+ @Override
+ public Boolean execute(final PreparedStatement input) throws Exception {
+ return input.execute();
+ }
+ });
+ MetricsContext.stop(context);
+ return result.get(0);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/StatementExecutor.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/StatementExecutor.java
new file mode 100644
index 0000000000000..2a25040695353
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/executor/StatementExecutor.java
@@ -0,0 +1,237 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.executor;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import com.codahale.metrics.Timer.Context;
+import com.dangdang.ddframe.rdb.sharding.metrics.MetricsContext;
+
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 多线程执行静态语句对象请求的执行器.
+ *
+ * @author gaohongtao
+ */
+@RequiredArgsConstructor
+public final class StatementExecutor {
+
+ private final Collection statements = new ArrayList<>();
+
+ /**
+ * 添加静态语句对象至执行上下文.
+ *
+ * @param sql 转换后的SQL语句
+ * @param statement 静态语句对象
+ */
+ public void addStatement(final String sql, final Statement statement) {
+ statements.add(new StatementEntity(sql, statement));
+ }
+
+ /**
+ * 执行SQL查询.
+ *
+ * @return 结果集列表
+ * @throws SQLException SQL异常
+ */
+ public List executeQuery() throws SQLException {
+ Context context = MetricsContext.start("ShardingStatement-executeQuery");
+ List result;
+ if (1 == statements.size()) {
+ StatementEntity entity = statements.iterator().next();
+ result = Arrays.asList(entity.statement.executeQuery(entity.sql));
+ MetricsContext.stop(context);
+ return result;
+ }
+ result = ExecutorEngine.execute(statements, new ExecuteUnit() {
+
+ @Override
+ public ResultSet execute(final StatementEntity input) throws Exception {
+ return input.statement.executeQuery(input.sql);
+ }
+ });
+ MetricsContext.stop(context);
+ return result;
+ }
+
+ /**
+ * 执行SQL更新.
+ *
+ * @return 更新数量
+ * @throws SQLException SQL异常
+ */
+ public int executeUpdate() throws SQLException {
+ return executeUpdate(new Updater() {
+
+ @Override
+ public int executeUpdate(final Statement statement, final String sql) throws SQLException {
+ return statement.executeUpdate(sql);
+ }
+ });
+ }
+
+ public int executeUpdate(final int autoGeneratedKeys) throws SQLException {
+ return executeUpdate(new Updater() {
+
+ @Override
+ public int executeUpdate(final Statement statement, final String sql) throws SQLException {
+ return statement.executeUpdate(sql, autoGeneratedKeys);
+ }
+ });
+ }
+
+ public int executeUpdate(final int[] columnIndexes) throws SQLException {
+ return executeUpdate(new Updater() {
+
+ @Override
+ public int executeUpdate(final Statement statement, final String sql) throws SQLException {
+ return statement.executeUpdate(sql, columnIndexes);
+ }
+ });
+ }
+
+ public int executeUpdate(final String[] columnNames) throws SQLException {
+ return executeUpdate(new Updater() {
+
+ @Override
+ public int executeUpdate(final Statement statement, final String sql) throws SQLException {
+ return statement.executeUpdate(sql, columnNames);
+ }
+ });
+ }
+
+ private int executeUpdate(final Updater updater) throws SQLException {
+ Context context = MetricsContext.start("ShardingStatement-executeUpdate");
+ int result;
+ if (1 == statements.size()) {
+ StatementEntity entity = statements.iterator().next();
+ result = updater.executeUpdate(entity.statement, entity.sql);
+ MetricsContext.stop(context);
+ return result;
+ }
+ result = ExecutorEngine.execute(statements, new ExecuteUnit() {
+
+ @Override
+ public Integer execute(final StatementEntity input) throws Exception {
+ return updater.executeUpdate(input.statement, input.sql);
+ }
+ }, new MergeUnit() {
+
+ @Override
+ public Integer merge(final List results) {
+ int result = 0;
+ for (int each : results) {
+ result += each;
+ }
+ return result;
+ }
+ });
+ MetricsContext.stop(context);
+ return result;
+ }
+
+ /**
+ * 执行SQL请求.
+ *
+ * @return true表示执行DQL语句, false表示执行的DML语句
+ * @throws SQLException SQL异常
+ */
+ public boolean execute() throws SQLException {
+ return execute(new Executor() {
+
+ @Override
+ public boolean execute(final Statement statement, final String sql) throws SQLException {
+ return statement.execute(sql);
+ }
+ });
+ }
+
+ public boolean execute(final int autoGeneratedKeys) throws SQLException {
+ return execute(new Executor() {
+
+ @Override
+ public boolean execute(final Statement statement, final String sql) throws SQLException {
+ return statement.execute(sql, autoGeneratedKeys);
+ }
+ });
+ }
+
+ public boolean execute(final int[] columnIndexes) throws SQLException {
+ return execute(new Executor() {
+
+ @Override
+ public boolean execute(final Statement statement, final String sql) throws SQLException {
+ return statement.execute(sql, columnIndexes);
+ }
+ });
+ }
+
+ public boolean execute(final String[] columnNames) throws SQLException {
+ return execute(new Executor() {
+
+ @Override
+ public boolean execute(final Statement statement, final String sql) throws SQLException {
+ return statement.execute(sql, columnNames);
+ }
+ });
+ }
+
+ private boolean execute(final Executor executor) throws SQLException {
+ Context context = MetricsContext.start("ShardingStatement-execute");
+ if (1 == statements.size()) {
+ StatementEntity entity = statements.iterator().next();
+ boolean result = executor.execute(entity.statement, entity.sql);
+ MetricsContext.stop(context);
+ return result;
+ }
+ List result = ExecutorEngine.execute(statements, new ExecuteUnit() {
+
+ @Override
+ public Boolean execute(final StatementEntity input) throws Exception {
+ return executor.execute(input.statement, input.sql);
+ }
+ });
+ MetricsContext.stop(context);
+ return result.get(0);
+ }
+
+ private interface Updater {
+
+ int executeUpdate(Statement statement, String sql) throws SQLException;
+ }
+
+ private interface Executor {
+
+ boolean execute(Statement statement, String sql) throws SQLException;
+ }
+
+ @RequiredArgsConstructor
+ private class StatementEntity {
+
+ private final String sql;
+
+ private final Statement statement;
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/AbstractShardingResultSet.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/AbstractShardingResultSet.java
new file mode 100644
index 0000000000000..33f5fef29deb5
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/AbstractShardingResultSet.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractResultSetAdapter;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.Limit;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 支持分片的结果集抽象类.
+ *
+ * @author zhangliang
+ */
+@Slf4j
+public abstract class AbstractShardingResultSet extends AbstractResultSetAdapter {
+
+ private final Limit limit;
+
+ private boolean offsetSkipped;
+
+ private int readCount;
+
+ protected AbstractShardingResultSet(final List resultSets, final Limit limit) {
+ super(resultSets);
+ this.limit = limit;
+ setCurrentResultSet(resultSets.get(0));
+ }
+
+ @Override
+ public final boolean next() throws SQLException {
+ if (null != limit && !offsetSkipped) {
+ skipOffset();
+ }
+ return null == limit ? nextForSharding() : ++readCount <= limit.getRowCount() && nextForSharding();
+ }
+
+ private void skipOffset() {
+ for (int i = 0; i < limit.getOffset(); i++) {
+ try {
+ if (!nextForSharding()) {
+ break;
+ }
+ } catch (final SQLException ignored) {
+ log.warn("Skip result set error", ignored);
+ }
+ }
+ offsetSkipped = true;
+ }
+
+ /**
+ * 迭代结果集.
+ *
+ * @return true 可以继续访问 false 不能继续访问
+ * @throws SQLException
+ */
+ protected abstract boolean nextForSharding() throws SQLException;
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingConnection.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingConnection.java
new file mode 100644
index 0000000000000..a7c0ffff21831
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingConnection.java
@@ -0,0 +1,129 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.codahale.metrics.Timer.Context;
+import com.dangdang.ddframe.rdb.sharding.api.DatabaseType;
+import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
+import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractConnectionAdapter;
+import com.dangdang.ddframe.rdb.sharding.metrics.MetricsContext;
+import com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine;
+
+/**
+ * 支持分片的数据库连接.
+ *
+ * @author zhangliang
+ */
+public final class ShardingConnection extends AbstractConnectionAdapter {
+
+ private final ShardingRule shardingRule;
+
+ private final DatabaseMetaData metaData;
+
+ private Map connectionMap = new HashMap<>();
+
+ private SQLRouteEngine sqlRouteEngine;
+
+ public ShardingConnection(final ShardingRule shardingRule, final DatabaseMetaData metaData) throws SQLException {
+ this.shardingRule = shardingRule;
+ this.metaData = metaData;
+ sqlRouteEngine = new SQLRouteEngine(shardingRule, DatabaseType.valueFrom(metaData.getDatabaseProductName()));
+ }
+
+ /**
+ * 根据数据源名称获取相应的数据库连接.
+ *
+ * @param dataSourceName 数据源名称
+ * @return 数据库连接
+ */
+ public Connection getConnection(final String dataSourceName) throws SQLException {
+ if (connectionMap.containsKey(dataSourceName)) {
+ return connectionMap.get(dataSourceName);
+ }
+ Context context = MetricsContext.start("ShardingConnection-getConnection", dataSourceName);
+ Connection connection = shardingRule.getDataSourceRule().getDataSource(dataSourceName).getConnection();
+ MetricsContext.stop(context);
+ replayMethodsInvovation(connection);
+ connectionMap.put(dataSourceName, connection);
+ return connection;
+ }
+
+ @Override
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return metaData;
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(final String sql) throws SQLException {
+ return new ShardingPreparedStatement(sqlRouteEngine, this, sql);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException {
+ return new ShardingPreparedStatement(sqlRouteEngine, this, sql, resultSetType, resultSetConcurrency);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException {
+ return new ShardingPreparedStatement(sqlRouteEngine, this, sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(final String sql, final int autoGeneratedKeys) throws SQLException {
+ return new ShardingPreparedStatement(sqlRouteEngine, this, sql, autoGeneratedKeys);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(final String sql, final int[] columnIndexes) throws SQLException {
+ return new ShardingPreparedStatement(sqlRouteEngine, this, sql, columnIndexes);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(final String sql, final String[] columnNames) throws SQLException {
+ return new ShardingPreparedStatement(sqlRouteEngine, this, sql, columnNames);
+ }
+
+ @Override
+ public Statement createStatement() throws SQLException {
+ return new ShardingStatement(sqlRouteEngine, this);
+ }
+
+ @Override
+ public Statement createStatement(final int resultSetType, final int resultSetConcurrency) throws SQLException {
+ return new ShardingStatement(sqlRouteEngine, this, resultSetType, resultSetConcurrency);
+ }
+
+ @Override
+ public Statement createStatement(final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException {
+ return new ShardingStatement(sqlRouteEngine, this, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ @Override
+ public Collection getConnections() {
+ return connectionMap.values();
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatement.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatement.java
new file mode 100644
index 0000000000000..817790dd38413
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingPreparedStatement.java
@@ -0,0 +1,186 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.dangdang.ddframe.rdb.sharding.executor.PreparedStatementExecutor;
+import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractPreparedStatementAdapter;
+import com.dangdang.ddframe.rdb.sharding.merger.ResultSetFactory;
+import com.dangdang.ddframe.rdb.sharding.router.SQLExecutionUnit;
+import com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine;
+import com.dangdang.ddframe.rdb.sharding.router.SQLRouteResult;
+import com.google.common.collect.Lists;
+
+/**
+ * 支持分片的预编译语句对象.
+ *
+ * @author zhangliang
+ */
+public final class ShardingPreparedStatement extends AbstractPreparedStatementAdapter {
+
+ private final String sql;
+
+ private final Collection cachedRoutedPreparedStatements = new LinkedList<>();
+
+ private Integer autoGeneratedKeys;
+
+ private int[] columnIndexes;
+
+ private String[] columnNames;
+
+ private boolean hasExecuted;
+
+ private final List> batchParameters = new ArrayList<>();
+
+ public ShardingPreparedStatement(final SQLRouteEngine sqlRouteEngine, final ShardingConnection shardingConnection, final String sql) throws SQLException {
+ this(sqlRouteEngine, shardingConnection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
+ }
+
+ public ShardingPreparedStatement(final SQLRouteEngine sqlRouteEngine, final ShardingConnection shardingConnection,
+ final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException {
+ this(sqlRouteEngine, shardingConnection, sql, resultSetType, resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT);
+ }
+
+ public ShardingPreparedStatement(final SQLRouteEngine sqlRouteEngine, final ShardingConnection shardingConnection,
+ final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException {
+ super(sqlRouteEngine, shardingConnection, resultSetType, resultSetConcurrency, resultSetHoldability);
+ this.sql = sql;
+ }
+
+ public ShardingPreparedStatement(final SQLRouteEngine sqlRouteEngine, final ShardingConnection shardingConnection, final String sql, final int autoGeneratedKeys) throws SQLException {
+ this(sqlRouteEngine, shardingConnection, sql);
+ this.autoGeneratedKeys = autoGeneratedKeys;
+ }
+
+ public ShardingPreparedStatement(final SQLRouteEngine sqlRouteEngine, final ShardingConnection shardingConnection, final String sql, final int[] columnIndexes) throws SQLException {
+ this(sqlRouteEngine, shardingConnection, sql);
+ this.columnIndexes = columnIndexes;
+ }
+
+ public ShardingPreparedStatement(final SQLRouteEngine sqlRouteEngine, final ShardingConnection shardingConnection, final String sql, final String[] columnNames) throws SQLException {
+ this(sqlRouteEngine, shardingConnection, sql);
+ this.columnNames = columnNames;
+ }
+
+ @Override
+ public ResultSet executeQuery() throws SQLException {
+ hasExecuted = true;
+ setCurrentResultSet(ResultSetFactory.getResultSet(new PreparedStatementExecutor(getRoutedPreparedStatements()).executeQuery(), getMergeContext()));
+ return getCurrentResultSet();
+ }
+
+ @Override
+ public int executeUpdate() throws SQLException {
+ hasExecuted = true;
+ return new PreparedStatementExecutor(getRoutedPreparedStatements()).executeUpdate();
+ }
+
+ @Override
+ public boolean execute() throws SQLException {
+ hasExecuted = true;
+ return new PreparedStatementExecutor(getRoutedPreparedStatements()).execute();
+ }
+
+ @Override
+ public void addBatch() throws SQLException {
+ batchParameters.add(Lists.newArrayList(getParameters()));
+ getParameters().clear();
+ }
+
+ @Override
+ public void clearBatch() throws SQLException {
+ batchParameters.clear();
+ }
+
+ @Override
+ public int[] executeBatch() throws SQLException {
+ hasExecuted = true;
+ int[] result = new int[batchParameters.size()];
+ int i = 0;
+ for (List each : batchParameters) {
+ result[i++] = new PreparedStatementExecutor(routeSQL(each)).executeUpdate();
+ }
+ return result;
+ }
+
+ private Collection getRoutedPreparedStatements() throws SQLException {
+ if (!hasExecuted) {
+ return Collections.emptyList();
+ }
+ routeIfNeed();
+ return cachedRoutedPreparedStatements;
+ }
+
+ @Override
+ public Collection extends Statement> getRoutedStatements() throws SQLException {
+ return getRoutedPreparedStatements();
+ }
+
+ private void routeIfNeed() throws SQLException {
+ if (!cachedRoutedPreparedStatements.isEmpty()) {
+ return;
+ }
+ cachedRoutedPreparedStatements.addAll(routeSQL(getParameters()));
+ }
+
+ private List routeSQL(final List parameters) throws SQLException {
+ List result = new ArrayList<>();
+ SQLRouteResult sqlRouteResult = getSqlRouteEngine().route(sql, parameters);
+ setMergeContext(sqlRouteResult.getMergeContext());
+ for (SQLExecutionUnit each : sqlRouteResult.getExecutionUnits()) {
+ PreparedStatement preparedStatement = generatePrepareStatement(getShardingConnection().getConnection(each.getDataSource()), each.getSql());
+ replayMethodsInvovation(preparedStatement);
+ setParameters(preparedStatement, parameters);
+ result.add(preparedStatement);
+ }
+ return result;
+ }
+
+ private PreparedStatement generatePrepareStatement(final Connection conn, final String shardingSql) throws SQLException {
+ if (null != autoGeneratedKeys) {
+ return conn.prepareStatement(shardingSql, autoGeneratedKeys);
+ }
+ if (null != columnIndexes) {
+ return conn.prepareStatement(shardingSql, columnIndexes);
+ }
+ if (null != columnNames) {
+ return conn.prepareStatement(shardingSql, columnNames);
+ }
+ if (0 != getResultSetHoldability()) {
+ return conn.prepareStatement(shardingSql, getResultSetType(), getResultSetConcurrency(), getResultSetHoldability());
+ }
+ return conn.prepareStatement(shardingSql, getResultSetType(), getResultSetConcurrency());
+ }
+
+ private void setParameters(final PreparedStatement preparedStatement, final List parameters) throws SQLException {
+ int i = 1;
+ for (Object each : parameters) {
+ preparedStatement.setObject(i++, each);
+ }
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatement.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatement.java
new file mode 100644
index 0000000000000..cd62d2863e4ce
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingStatement.java
@@ -0,0 +1,194 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.dangdang.ddframe.rdb.sharding.executor.StatementExecutor;
+import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractStatementAdapter;
+import com.dangdang.ddframe.rdb.sharding.merger.ResultSetFactory;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext;
+import com.dangdang.ddframe.rdb.sharding.router.SQLExecutionUnit;
+import com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine;
+import com.dangdang.ddframe.rdb.sharding.router.SQLRouteResult;
+import com.google.common.base.Charsets;
+import com.google.common.hash.HashCode;
+import com.google.common.hash.Hashing;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 支持分片的静态语句对象.
+ *
+ * @author gaohongtao
+ */
+public class ShardingStatement extends AbstractStatementAdapter {
+
+ @Getter(AccessLevel.PROTECTED)
+ private final ShardingConnection shardingConnection;
+
+ @Getter(AccessLevel.PROTECTED)
+ private final SQLRouteEngine sqlRouteEngine;
+
+ @Getter
+ private final int resultSetType;
+
+ @Getter
+ private final int resultSetConcurrency;
+
+ @Getter
+ private final int resultSetHoldability;
+
+ private final Map cachedRoutedStatements = new HashMap<>();
+
+ @Getter(AccessLevel.PROTECTED)
+ @Setter(AccessLevel.PROTECTED)
+ private MergeContext mergeContext;
+
+ @Getter(AccessLevel.PROTECTED)
+ @Setter(AccessLevel.PROTECTED)
+ private ResultSet currentResultSet;
+
+ public ShardingStatement(final SQLRouteEngine sqlRouteEngine, final ShardingConnection shardingConnection) throws SQLException {
+ this(sqlRouteEngine, shardingConnection, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
+ }
+
+ public ShardingStatement(final SQLRouteEngine sqlRouteEngine, final ShardingConnection shardingConnection, final int resultSetType, final int resultSetConcurrency) throws SQLException {
+ this(sqlRouteEngine, shardingConnection, resultSetType, resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT);
+ }
+
+ public ShardingStatement(final SQLRouteEngine sqlRouteEngine, final ShardingConnection shardingConnection,
+ final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException {
+ super(Statement.class);
+ this.shardingConnection = shardingConnection;
+ this.sqlRouteEngine = sqlRouteEngine;
+ this.resultSetType = resultSetType;
+ this.resultSetConcurrency = resultSetConcurrency;
+ this.resultSetHoldability = resultSetHoldability;
+ }
+
+ @Override
+ public Connection getConnection() throws SQLException {
+ return shardingConnection;
+ }
+
+ @Override
+ public ResultSet executeQuery(final String sql) throws SQLException {
+ if (null != currentResultSet && !currentResultSet.isClosed()) {
+ currentResultSet.close();
+ }
+ currentResultSet = ResultSetFactory.getResultSet(generateExecutor(sql).executeQuery(), mergeContext);
+ return currentResultSet;
+ }
+
+ @Override
+ public int executeUpdate(final String sql) throws SQLException {
+ return generateExecutor(sql).executeUpdate();
+ }
+
+ @Override
+ public int executeUpdate(final String sql, final int autoGeneratedKeys) throws SQLException {
+ return generateExecutor(sql).executeUpdate(autoGeneratedKeys);
+ }
+
+ @Override
+ public int executeUpdate(final String sql, final int[] columnIndexes) throws SQLException {
+ return generateExecutor(sql).executeUpdate(columnIndexes);
+ }
+
+ @Override
+ public int executeUpdate(final String sql, final String[] columnNames) throws SQLException {
+ return generateExecutor(sql).executeUpdate(columnNames);
+ }
+
+ @Override
+ public boolean execute(final String sql) throws SQLException {
+ return generateExecutor(sql).execute();
+ }
+
+ @Override
+ public boolean execute(final String sql, final int autoGeneratedKeys) throws SQLException {
+ return generateExecutor(sql).execute(autoGeneratedKeys);
+ }
+
+ @Override
+ public boolean execute(final String sql, final int[] columnIndexes) throws SQLException {
+ return generateExecutor(sql).execute(columnIndexes);
+ }
+
+ @Override
+ public boolean execute(final String sql, final String[] columnNames) throws SQLException {
+ return generateExecutor(sql).execute(columnNames);
+ }
+
+ private StatementExecutor generateExecutor(final String sql) throws SQLException {
+ StatementExecutor result = new StatementExecutor();
+ SQLRouteResult sqlRouteResult = sqlRouteEngine.route(sql, Collections.emptyList());
+ mergeContext = sqlRouteResult.getMergeContext();
+ for (SQLExecutionUnit each : sqlRouteResult.getExecutionUnits()) {
+ result.addStatement(each.getSql(), generateStatement(each.getSql(), each.getDataSource()));
+ }
+ return result;
+ }
+
+ private Statement generateStatement(final String sql, final String dataSourceName) throws SQLException {
+ HashCode hashCode = Hashing.md5().newHasher().putString(sql, Charsets.UTF_8).putString(dataSourceName, Charsets.UTF_8).hash();
+ if (cachedRoutedStatements.containsKey(hashCode)) {
+ return cachedRoutedStatements.get(hashCode);
+ }
+ Connection connection = shardingConnection.getConnection(dataSourceName);
+ Statement result;
+ if (0 == resultSetHoldability) {
+ result = connection.createStatement(resultSetType, resultSetConcurrency);
+ } else {
+ result = connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+ replayMethodsInvovation(result);
+ cachedRoutedStatements.put(hashCode, result);
+ return result;
+ }
+
+ @Override
+ public ResultSet getResultSet() throws SQLException {
+ if (null != currentResultSet) {
+ return currentResultSet;
+ }
+ List resultSets = new ArrayList<>(getRoutedStatements().size());
+ for (Statement each : getRoutedStatements()) {
+ resultSets.add(each.getResultSet());
+ }
+ currentResultSet = ResultSetFactory.getResultSet(resultSets, mergeContext);
+ return currentResultSet;
+ }
+
+ @Override
+ public Collection extends Statement> getRoutedStatements() throws SQLException {
+ return cachedRoutedStatements.values();
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractConnectionAdapter.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractConnectionAdapter.java
new file mode 100644
index 0000000000000..d425a9f0ed109
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractConnectionAdapter.java
@@ -0,0 +1,142 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.adapter;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.util.Collection;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.unsupported.AbstractUnsupportedOperationConnection;
+
+/**
+ * 数据库连接适配类.
+ *
+ * @author zhangliang
+ */
+public abstract class AbstractConnectionAdapter extends AbstractUnsupportedOperationConnection {
+
+ private boolean autoCommit = true;
+
+ private boolean readOnly = true;
+
+ private boolean closed;
+
+ private int transactionIsolation = TRANSACTION_READ_UNCOMMITTED;
+
+ protected abstract Collection getConnections();
+
+ @Override
+ public final boolean getAutoCommit() throws SQLException {
+ return autoCommit;
+ }
+
+ @Override
+ public final void setAutoCommit(final boolean autoCommit) throws SQLException {
+ this.autoCommit = autoCommit;
+ if (getConnections().isEmpty()) {
+ recordMethodInvocation(Connection.class, "setAutoCommit", new Class[] {boolean.class}, new Object[] {autoCommit});
+ return;
+ }
+ for (Connection each : getConnections()) {
+ each.setAutoCommit(autoCommit);
+ }
+ }
+
+ @Override
+ public final void commit() throws SQLException {
+ for (Connection each : getConnections()) {
+ each.commit();
+ }
+ }
+
+ @Override
+ public final void rollback() throws SQLException {
+ for (Connection each : getConnections()) {
+ each.rollback();
+ }
+ }
+
+ @Override
+ public final void close() throws SQLException {
+ for (Connection each : getConnections()) {
+ each.close();
+ }
+ closed = true;
+ }
+
+ @Override
+ public final boolean isClosed() throws SQLException {
+ return closed;
+ }
+
+ @Override
+ public final boolean isReadOnly() throws SQLException {
+ return readOnly;
+ }
+
+ @Override
+ public final void setReadOnly(final boolean readOnly) throws SQLException {
+ this.readOnly = readOnly;
+ if (getConnections().isEmpty()) {
+ recordMethodInvocation(Connection.class, "setReadOnly", new Class[] {boolean.class}, new Object[] {readOnly});
+ return;
+ }
+ for (Connection each : getConnections()) {
+ each.setReadOnly(readOnly);
+ }
+ }
+
+ @Override
+ public final int getTransactionIsolation() throws SQLException {
+ return transactionIsolation;
+ }
+
+ @Override
+ public final void setTransactionIsolation(final int level) throws SQLException {
+ transactionIsolation = level;
+ if (getConnections().isEmpty()) {
+ recordMethodInvocation(Connection.class, "setTransactionIsolation", new Class[] {int.class}, new Object[] {level});
+ return;
+ }
+ for (Connection each : getConnections()) {
+ each.setTransactionIsolation(level);
+ }
+ }
+
+ // -------以下代码与MySQL实现保持一致.-------
+
+ @Override
+ public SQLWarning getWarnings() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public void clearWarnings() throws SQLException {
+ }
+
+ @Override
+ public final int getHoldability() throws SQLException {
+ return ResultSet.CLOSE_CURSORS_AT_COMMIT;
+ }
+
+ @Override
+ public final void setHoldability(final int holdability) throws SQLException {
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractDataSourceAdapter.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractDataSourceAdapter.java
new file mode 100644
index 0000000000000..4c7216238a878
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractDataSourceAdapter.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.adapter;
+
+import java.io.PrintWriter;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.logging.Logger;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.unsupported.AbstractUnsupportedOperationDataSource;
+
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 数据源适配类.
+ *
+ * @author zhangliang
+ */
+@RequiredArgsConstructor
+public abstract class AbstractDataSourceAdapter extends AbstractUnsupportedOperationDataSource {
+
+ private PrintWriter logWriter = new PrintWriter(System.out);
+
+ @Override
+ public final PrintWriter getLogWriter() throws SQLException {
+ return logWriter;
+ }
+
+ @Override
+ public final void setLogWriter(final PrintWriter out) throws SQLException {
+ this.logWriter = out;
+ }
+
+ @Override
+ public final Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractPreparedStatementAdapter.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractPreparedStatementAdapter.java
new file mode 100644
index 0000000000000..f160fc963e5b6
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractPreparedStatementAdapter.java
@@ -0,0 +1,275 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.adapter;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection;
+import com.dangdang.ddframe.rdb.sharding.jdbc.unsupported.AbstractUnsupportedOperationPreparedStatement;
+import com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine;
+
+import lombok.Getter;
+
+/**
+ * 预编译语句对象的适配类.
+ *
+ *
+ * 封装与分片核心逻辑不相关的方法.
+ *
+ *
+ * @author zhangliang
+ */
+public abstract class AbstractPreparedStatementAdapter extends AbstractUnsupportedOperationPreparedStatement {
+
+ @Getter
+ private final List parameters = new ArrayList<>();
+
+ public AbstractPreparedStatementAdapter(final SQLRouteEngine sqlRouteEngine, final ShardingConnection shardingConnection,
+ final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException {
+ super(sqlRouteEngine, shardingConnection, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ @Override
+ public final void setNull(final int parameterIndex, final int sqlType) throws SQLException {
+ setParameter(parameterIndex, null);
+ }
+
+ @Override
+ public final void setNull(final int parameterIndex, final int sqlType, final String typeName) throws SQLException {
+ setParameter(parameterIndex, null);
+ }
+
+ @Override
+ public final void setBoolean(final int parameterIndex, final boolean x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setByte(final int parameterIndex, final byte x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setShort(final int parameterIndex, final short x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setInt(final int parameterIndex, final int x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setLong(final int parameterIndex, final long x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setFloat(final int parameterIndex, final float x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setDouble(final int parameterIndex, final double x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setString(final int parameterIndex, final String x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setBigDecimal(final int parameterIndex, final BigDecimal x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setDate(final int parameterIndex, final Date x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setDate(final int parameterIndex, final Date x, final Calendar cal) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setTime(final int parameterIndex, final Time x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setTime(final int parameterIndex, final Time x, final Calendar cal) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setTimestamp(final int parameterIndex, final Timestamp x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setTimestamp(final int parameterIndex, final Timestamp x, final Calendar cal) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setBytes(final int parameterIndex, final byte[] x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setBlob(final int parameterIndex, final Blob x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setBlob(final int parameterIndex, final InputStream x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setBlob(final int parameterIndex, final InputStream x, final long length) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setClob(final int parameterIndex, final Clob x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setClob(final int parameterIndex, final Reader x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setClob(final int parameterIndex, final Reader x, final long length) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setAsciiStream(final int parameterIndex, final InputStream x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setAsciiStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setAsciiStream(final int parameterIndex, final InputStream x, final long length) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setUnicodeStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setBinaryStream(final int parameterIndex, final InputStream x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setBinaryStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setBinaryStream(final int parameterIndex, final InputStream x, final long length) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setCharacterStream(final int parameterIndex, final Reader x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setCharacterStream(final int parameterIndex, final Reader x, final int length) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setCharacterStream(final int parameterIndex, final Reader x, final long length) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setURL(final int parameterIndex, final URL x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setSQLXML(final int parameterIndex, final SQLXML x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setRef(final int parameterIndex, final Ref x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setObject(final int parameterIndex, final Object x) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setObject(final int parameterIndex, final Object x, final int targetSqlType) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void setObject(final int parameterIndex, final Object x, final int targetSqlType, final int scaleOrLength) throws SQLException {
+ setParameter(parameterIndex, x);
+ }
+
+ @Override
+ public final void clearParameters() throws SQLException {
+ parameters.clear();
+ }
+
+ private void setParameter(final int index, final Object x) {
+ int extendedSize = index - parameters.size();
+ if (extendedSize > 1) {
+ while (--extendedSize > 0) {
+ parameters.add(null);
+ }
+ }
+ parameters.add(index - 1, x);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractResultSetAdapter.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractResultSetAdapter.java
new file mode 100644
index 0000000000000..837389d11c257
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractResultSetAdapter.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.adapter;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.util.List;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 处理多结果集的适配器.
+ *
+ * @author zhangliang
+ */
+@RequiredArgsConstructor
+public abstract class AbstractResultSetAdapter extends AbstractResultSetGetterAdapter {
+
+ @Getter
+ private final List resultSets;
+
+ private boolean closed;
+
+ @Override
+ public final void close() throws SQLException {
+ for (ResultSet each : resultSets) {
+ each.close();
+ }
+ closed = true;
+ }
+
+ @Override
+ public final boolean isClosed() throws SQLException {
+ return closed;
+ }
+
+ @Override
+ public final boolean wasNull() throws SQLException {
+ return getCurrentResultSet().wasNull();
+ }
+
+ @Override
+ public final int getFetchDirection() throws SQLException {
+ return getCurrentResultSet().getFetchDirection();
+ }
+
+ @Override
+ public final void setFetchDirection(final int direction) throws SQLException {
+ for (ResultSet each : resultSets) {
+ each.setFetchDirection(direction);
+ }
+ }
+
+ @Override
+ public final int getFetchSize() throws SQLException {
+ return getCurrentResultSet().getFetchSize();
+ }
+
+ @Override
+ public final void setFetchSize(final int rows) throws SQLException {
+ for (ResultSet each : resultSets) {
+ each.setFetchSize(rows);
+ }
+ }
+
+ @Override
+ public final int getType() throws SQLException {
+ return getCurrentResultSet().getType();
+ }
+
+ @Override
+ public final int getConcurrency() throws SQLException {
+ return getCurrentResultSet().getConcurrency();
+ }
+
+ @Override
+ public final Statement getStatement() throws SQLException {
+ return getCurrentResultSet().getStatement();
+ }
+
+ @Override
+ public final SQLWarning getWarnings() throws SQLException {
+ return getCurrentResultSet().getWarnings();
+ }
+
+ @Override
+ public final void clearWarnings() throws SQLException {
+ getCurrentResultSet().clearWarnings();
+ }
+
+ @Override
+ public final ResultSetMetaData getMetaData() throws SQLException {
+ return getCurrentResultSet().getMetaData();
+ }
+
+ @Override
+ public final int findColumn(final String columnLabel) throws SQLException {
+ return getCurrentResultSet().findColumn(columnLabel);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractResultSetGetterAdapter.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractResultSetGetterAdapter.java
new file mode 100644
index 0000000000000..b84c4b5c35f3c
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractResultSetGetterAdapter.java
@@ -0,0 +1,327 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.adapter;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Map;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.unsupported.AbstractUnsupportedOperationResultSet;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+
+/**
+ * 处理多结果集的适配器.
+ *
+ * @author zhangliang
+ */
+@RequiredArgsConstructor
+public abstract class AbstractResultSetGetterAdapter extends AbstractUnsupportedOperationResultSet {
+
+ @Getter(AccessLevel.PROTECTED)
+ @Setter(AccessLevel.PROTECTED)
+ private ResultSet currentResultSet;
+
+ @Override
+ public final boolean getBoolean(final int columnIndex) throws SQLException {
+ return currentResultSet.getBoolean(columnIndex);
+ }
+
+ @Override
+ public final boolean getBoolean(final String columnLabel) throws SQLException {
+ return currentResultSet.getBoolean(columnLabel);
+ }
+
+ @Override
+ public final byte getByte(final int columnIndex) throws SQLException {
+ return currentResultSet.getByte(columnIndex);
+ }
+
+ @Override
+ public final byte getByte(final String columnLabel) throws SQLException {
+ return currentResultSet.getByte(columnLabel);
+ }
+
+ @Override
+ public final short getShort(final int columnIndex) throws SQLException {
+ return currentResultSet.getShort(columnIndex);
+ }
+
+ @Override
+ public final short getShort(final String columnLabel) throws SQLException {
+ return currentResultSet.getShort(columnLabel);
+ }
+
+ @Override
+ public final int getInt(final int columnIndex) throws SQLException {
+ return currentResultSet.getInt(columnIndex);
+ }
+
+ @Override
+ public final int getInt(final String columnLabel) throws SQLException {
+ return currentResultSet.getInt(columnLabel);
+ }
+
+ @Override
+ public final long getLong(final int columnIndex) throws SQLException {
+ return currentResultSet.getLong(columnIndex);
+ }
+
+ @Override
+ public final long getLong(final String columnLabel) throws SQLException {
+ return currentResultSet.getLong(columnLabel);
+ }
+
+ @Override
+ public final float getFloat(final int columnIndex) throws SQLException {
+ return currentResultSet.getFloat(columnIndex);
+ }
+
+ @Override
+ public final float getFloat(final String columnLabel) throws SQLException {
+ return currentResultSet.getFloat(columnLabel);
+ }
+
+ @Override
+ public final double getDouble(final int columnIndex) throws SQLException {
+ return currentResultSet.getDouble(columnIndex);
+ }
+
+ @Override
+ public final double getDouble(final String columnLabel) throws SQLException {
+ return currentResultSet.getDouble(columnLabel);
+ }
+
+ @Override
+ public final String getString(final int columnIndex) throws SQLException {
+ return currentResultSet.getString(columnIndex);
+ }
+
+ @Override
+ public final String getString(final String columnLabel) throws SQLException {
+ return currentResultSet.getString(columnLabel);
+ }
+
+ @Override
+ public final BigDecimal getBigDecimal(final int columnIndex) throws SQLException {
+ return currentResultSet.getBigDecimal(columnIndex);
+ }
+
+ @Override
+ public final BigDecimal getBigDecimal(final String columnLabel) throws SQLException {
+ return currentResultSet.getBigDecimal(columnLabel);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public final BigDecimal getBigDecimal(final int columnIndex, final int scale) throws SQLException {
+ return currentResultSet.getBigDecimal(columnIndex, scale);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public final BigDecimal getBigDecimal(final String columnLabel, final int scale) throws SQLException {
+ return currentResultSet.getBigDecimal(columnLabel, scale);
+ }
+
+ @Override
+ public final byte[] getBytes(final int columnIndex) throws SQLException {
+ return currentResultSet.getBytes(columnIndex);
+ }
+
+ @Override
+ public final byte[] getBytes(final String columnLabel) throws SQLException {
+ return currentResultSet.getBytes(columnLabel);
+ }
+
+ @Override
+ public final Date getDate(final int columnIndex) throws SQLException {
+ return currentResultSet.getDate(columnIndex);
+ }
+
+ @Override
+ public final Date getDate(final String columnLabel) throws SQLException {
+ return currentResultSet.getDate(columnLabel);
+ }
+
+ @Override
+ public final Date getDate(final int columnIndex, final Calendar cal) throws SQLException {
+ return currentResultSet.getDate(columnIndex, cal);
+ }
+
+ @Override
+ public final Date getDate(final String columnLabel, final Calendar cal) throws SQLException {
+ return currentResultSet.getDate(columnLabel, cal);
+ }
+
+ @Override
+ public final Time getTime(final int columnIndex) throws SQLException {
+ return currentResultSet.getTime(columnIndex);
+ }
+
+ @Override
+ public final Time getTime(final String columnLabel) throws SQLException {
+ return currentResultSet.getTime(columnLabel);
+ }
+
+ @Override
+ public final Time getTime(final int columnIndex, final Calendar cal) throws SQLException {
+ return currentResultSet.getTime(columnIndex, cal);
+ }
+
+ @Override
+ public final Time getTime(final String columnLabel, final Calendar cal) throws SQLException {
+ return currentResultSet.getTime(columnLabel, cal);
+ }
+
+ @Override
+ public final Timestamp getTimestamp(final int columnIndex) throws SQLException {
+ return currentResultSet.getTimestamp(columnIndex);
+ }
+
+ @Override
+ public final Timestamp getTimestamp(final String columnLabel) throws SQLException {
+ return currentResultSet.getTimestamp(columnLabel);
+ }
+
+ @Override
+ public final Timestamp getTimestamp(final int columnIndex, final Calendar cal) throws SQLException {
+ return currentResultSet.getTimestamp(columnIndex, cal);
+ }
+
+ @Override
+ public final Timestamp getTimestamp(final String columnLabel, final Calendar cal) throws SQLException {
+ return currentResultSet.getTimestamp(columnLabel, cal);
+ }
+
+ @Override
+ public final InputStream getAsciiStream(final int columnIndex) throws SQLException {
+ return currentResultSet.getAsciiStream(columnIndex);
+ }
+
+ @Override
+ public final InputStream getAsciiStream(final String columnLabel) throws SQLException {
+ return currentResultSet.getAsciiStream(columnLabel);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public final InputStream getUnicodeStream(final int columnIndex) throws SQLException {
+ return currentResultSet.getUnicodeStream(columnIndex);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public final InputStream getUnicodeStream(final String columnLabel) throws SQLException {
+ return currentResultSet.getUnicodeStream(columnLabel);
+ }
+
+ @Override
+ public final InputStream getBinaryStream(final int columnIndex) throws SQLException {
+ return currentResultSet.getBinaryStream(columnIndex);
+ }
+
+ @Override
+ public final InputStream getBinaryStream(final String columnLabel) throws SQLException {
+ return currentResultSet.getBinaryStream(columnLabel);
+ }
+
+ @Override
+ public final Reader getCharacterStream(final int columnIndex) throws SQLException {
+ return currentResultSet.getCharacterStream(columnIndex);
+ }
+
+ @Override
+ public final Reader getCharacterStream(final String columnLabel) throws SQLException {
+ return currentResultSet.getCharacterStream(columnLabel);
+ }
+
+ @Override
+ public final Blob getBlob(final int columnIndex) throws SQLException {
+ return currentResultSet.getBlob(columnIndex);
+ }
+
+ @Override
+ public final Blob getBlob(final String columnLabel) throws SQLException {
+ return currentResultSet.getBlob(columnLabel);
+ }
+
+ @Override
+ public final Clob getClob(final int columnIndex) throws SQLException {
+ return currentResultSet.getClob(columnIndex);
+ }
+
+ @Override
+ public final Clob getClob(final String columnLabel) throws SQLException {
+ return currentResultSet.getClob(columnLabel);
+ }
+
+ @Override
+ public final URL getURL(final int columnIndex) throws SQLException {
+ return currentResultSet.getURL(columnIndex);
+ }
+
+ @Override
+ public final URL getURL(final String columnLabel) throws SQLException {
+ return currentResultSet.getURL(columnLabel);
+ }
+
+ @Override
+ public final SQLXML getSQLXML(final int columnIndex) throws SQLException {
+ return currentResultSet.getSQLXML(columnIndex);
+ }
+
+ @Override
+ public final SQLXML getSQLXML(final String columnLabel) throws SQLException {
+ return currentResultSet.getSQLXML(columnLabel);
+ }
+
+ @Override
+ public final Object getObject(final int columnIndex) throws SQLException {
+ return currentResultSet.getObject(columnIndex);
+ }
+
+ @Override
+ public final Object getObject(final String columnLabel) throws SQLException {
+ return currentResultSet.getObject(columnLabel);
+ }
+
+ @Override
+ public final Object getObject(final int columnIndex, final Map> map) throws SQLException {
+ return currentResultSet.getObject(columnIndex, map);
+ }
+
+ @Override
+ public final Object getObject(final String columnLabel, final Map> map) throws SQLException {
+ return currentResultSet.getObject(columnLabel, map);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractStatementAdapter.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractStatementAdapter.java
new file mode 100644
index 0000000000000..d4296606ffd4b
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractStatementAdapter.java
@@ -0,0 +1,163 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.adapter;
+
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.util.Collection;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.unsupported.AbstractUnsupportedOperationStatement;
+
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 静态语句对象适配类.
+ *
+ * @author gaohongtao
+ */
+@RequiredArgsConstructor
+public abstract class AbstractStatementAdapter extends AbstractUnsupportedOperationStatement {
+
+ private final Class extends Statement> recordTargetClass;
+
+ private boolean closed;
+
+ private boolean poolable;
+
+ private int fetchSize;
+
+ @Override
+ public final void close() throws SQLException {
+ for (Statement each : getRoutedStatements()) {
+ each.close();
+ }
+ closed = true;
+ getRoutedStatements().clear();
+ }
+
+ @Override
+ public final boolean isClosed() throws SQLException {
+ return closed;
+ }
+
+ @Override
+ public final boolean isPoolable() throws SQLException {
+ return poolable;
+ }
+
+ @Override
+ public final void setPoolable(final boolean poolable) throws SQLException {
+ this.poolable = poolable;
+ if (getRoutedStatements().isEmpty()) {
+ recordMethodInvocation(recordTargetClass, "setPoolable", new Class[] {boolean.class}, new Object[] {poolable});
+ return;
+ }
+ for (Statement each : getRoutedStatements()) {
+ each.setPoolable(poolable);
+ }
+ }
+
+ @Override
+ public final int getFetchSize() throws SQLException {
+ return fetchSize;
+ }
+
+ @Override
+ public final void setFetchSize(final int rows) throws SQLException {
+ this.fetchSize = rows;
+ if (getRoutedStatements().isEmpty()) {
+ recordMethodInvocation(recordTargetClass, "setFetchSize", new Class[] {int.class}, new Object[] {rows});
+ return;
+ }
+ for (Statement each : getRoutedStatements()) {
+ each.setFetchSize(rows);
+ }
+ }
+
+ @Override
+ public final void setEscapeProcessing(final boolean enable) throws SQLException {
+ if (getRoutedStatements().isEmpty()) {
+ recordMethodInvocation(recordTargetClass, "setEscapeProcessing", new Class[] {boolean.class}, new Object[] {enable});
+ return;
+ }
+ for (Statement each : getRoutedStatements()) {
+ each.setEscapeProcessing(enable);
+ }
+ }
+
+ @Override
+ public final void cancel() throws SQLException {
+ for (Statement each : getRoutedStatements()) {
+ each.cancel();
+ }
+ }
+
+ @Override
+ public final void setCursorName(final String name) throws SQLException {
+ if (getRoutedStatements().isEmpty()) {
+ recordMethodInvocation(recordTargetClass, "setCursorName", new Class[] {String.class}, new Object[] {name});
+ return;
+ }
+ for (Statement each : getRoutedStatements()) {
+ each.setCursorName(name);
+ }
+ }
+
+ @Override
+ public final int getUpdateCount() throws SQLException {
+ int result = 0;
+ for (Statement each : getRoutedStatements()) {
+ result += each.getUpdateCount();
+ }
+ return result;
+ }
+
+ @Override
+ public SQLWarning getWarnings() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public void clearWarnings() throws SQLException {
+ }
+
+ /*
+ * 只有存储过程会出现多结果集, 因此不支持.
+ */
+ @Override
+ public final boolean getMoreResults() throws SQLException {
+ return false;
+ }
+
+ @Override
+ public final boolean getMoreResults(final int current) throws SQLException {
+ return false;
+ }
+
+
+
+ /**
+ * 获取路由的静态语句对象集合.
+ *
+ * @return 路由的静态语句对象集合
+ * @throws SQLException
+ */
+ public abstract Collection extends Statement> getRoutedStatements() throws SQLException;
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/WrapperAdapter.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/WrapperAdapter.java
new file mode 100644
index 0000000000000..c7fae0c29ecf4
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/WrapperAdapter.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.adapter;
+
+import java.sql.SQLException;
+import java.sql.Wrapper;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import com.dangdang.ddframe.rdb.sharding.exception.ShardingJdbcException;
+import com.dangdang.ddframe.rdb.sharding.jdbc.util.JdbcMethodInvocation;
+
+/**
+ * JDBC Wrapper适配类.
+ *
+ * @author zhangliang
+ */
+public class WrapperAdapter implements Wrapper {
+
+ private Collection jdbcMethodInvocations = new ArrayList<>();
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public final T unwrap(final Class iface) throws SQLException {
+ if (isWrapperFor(iface)) {
+ return (T) this;
+ }
+ throw new SQLException(String.format("[%s] cannot be unwrapped as [%s]", getClass().getName(), iface.getName()));
+ }
+
+ @Override
+ public final boolean isWrapperFor(final Class> iface) throws SQLException {
+ return iface.isInstance(this);
+ }
+
+ /**
+ * 记录方法调用.
+ *
+ * @param targetClass 目标类
+ * @param methodName 方法名称
+ * @param argumentTypes 参数类型
+ * @param arguments 参数
+ */
+ protected final void recordMethodInvocation(final Class> targetClass, final String methodName, final Class>[] argumentTypes, final Object[] arguments) {
+ try {
+ jdbcMethodInvocations.add(new JdbcMethodInvocation(targetClass.getMethod(methodName, argumentTypes), arguments));
+ } catch (final NoSuchMethodException ex) {
+ throw new ShardingJdbcException(ex);
+ }
+ }
+
+ /**
+ * 回放记录的方法调用.
+ *
+ * @param target 目标对象
+ */
+ protected final void replayMethodsInvovation(final Object target) {
+ for (JdbcMethodInvocation each : jdbcMethodInvocations) {
+ each.invoke(target);
+ }
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractResultSetUpdaterAdapter.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractResultSetUpdaterAdapter.java
new file mode 100644
index 0000000000000..2848428c32e41
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractResultSetUpdaterAdapter.java
@@ -0,0 +1,455 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.unsupported;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.WrapperAdapter;
+
+/**
+ * 更新结果集的适配器.
+ *
+ * @author zhangliang
+ */
+public abstract class AbstractResultSetUpdaterAdapter extends WrapperAdapter implements ResultSet {
+
+ @Override
+ public final void updateNull(final int columnIndex) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNull(final String columnLabel) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBoolean(final int columnIndex, final boolean x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBoolean(final String columnLabel, final boolean x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateByte(final int columnIndex, final byte x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateByte(final String columnLabel, final byte x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateShort(final int columnIndex, final short x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateShort(final String columnLabel, final short x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateInt(final int columnIndex, final int x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateInt(final String columnLabel, final int x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateLong(final int columnIndex, final long x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateLong(final String columnLabel, final long x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateFloat(final int columnIndex, final float x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateFloat(final String columnLabel, final float x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateDouble(final int columnIndex, final double x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateDouble(final String columnLabel, final double x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBigDecimal(final int columnIndex, final BigDecimal x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBigDecimal(final String columnLabel, final BigDecimal x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateString(final int columnIndex, final String x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateString(final String columnLabel, final String x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNString(final int columnIndex, final String nString) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNString(final String columnLabel, final String nString) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBytes(final int columnIndex, final byte[] x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBytes(final String columnLabel, final byte[] x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateDate(final int columnIndex, final Date x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateDate(final String columnLabel, final Date x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateTime(final int columnIndex, final Time x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateTime(final String columnLabel, final Time x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateTimestamp(final int columnIndex, final Timestamp x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateTimestamp(final String columnLabel, final Timestamp x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateAsciiStream(final int columnIndex, final InputStream inputStream) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateAsciiStream(final String columnLabel, final InputStream inputStream) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateAsciiStream(final int columnIndex, final InputStream x, final int length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateAsciiStream(final String columnLabel, final InputStream x, final int length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateAsciiStream(final int columnIndex, final InputStream inputStream, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateAsciiStream(final String columnLabel, final InputStream inputStream, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBinaryStream(final int columnIndex, final InputStream x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBinaryStream(final String columnLabel, final InputStream x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBinaryStream(final int columnIndex, final InputStream x, final int length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBinaryStream(final String columnLabel, final InputStream x, final int length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBinaryStream(final int columnIndex, final InputStream x, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBinaryStream(final String columnLabel, final InputStream x, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateCharacterStream(final int columnIndex, final Reader x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateCharacterStream(final String columnLabel, final Reader x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateCharacterStream(final int columnIndex, final Reader x, final int length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateCharacterStream(final String columnLabel, final Reader reader, final int length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateCharacterStream(final int columnIndex, final Reader x, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateCharacterStream(final String columnLabel, final Reader reader, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNCharacterStream(final int columnIndex, final Reader x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNCharacterStream(final String columnLabel, final Reader x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNCharacterStream(final int columnIndex, final Reader x, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNCharacterStream(final String columnLabel, final Reader x, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateObject(final int columnIndex, final Object x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateObject(final String columnLabel, final Object x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateObject(final int columnIndex, final Object x, final int scaleOrLength) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateObject(final String columnLabel, final Object x, final int scaleOrLength) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateRef(final int columnIndex, final Ref x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateRef(final String columnLabel, final Ref x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBlob(final int columnIndex, final Blob x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBlob(final String columnLabel, final Blob x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBlob(final int columnIndex, final InputStream inputStream) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBlob(final String columnLabel, final InputStream inputStream) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBlob(final int columnIndex, final InputStream inputStream, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateBlob(final String columnLabel, final InputStream inputStream, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateClob(final int columnIndex, final Clob x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateClob(final String columnLabel, final Clob x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateClob(final int columnIndex, final Reader reader) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateClob(final String columnLabel, final Reader reader) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateClob(final int columnIndex, final Reader reader, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateClob(final String columnLabel, final Reader reader, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNClob(final int columnIndex, final NClob nClob) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNClob(final String columnLabel, final NClob nClob) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNClob(final int columnIndex, final Reader reader) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNClob(final String columnLabel, final Reader reader) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNClob(final int columnIndex, final Reader reader, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateNClob(final String columnLabel, final Reader reader, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateArray(final int columnIndex, final Array x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateArray(final String columnLabel, final Array x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateRowId(final int columnIndex, final RowId x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateRowId(final String columnLabel, final RowId x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateSQLXML(final int columnIndex, final SQLXML xmlObject) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+
+ @Override
+ public final void updateSQLXML(final String columnLabel, final SQLXML xmlObject) throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateXXX");
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationConnection.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationConnection.java
new file mode 100644
index 0000000000000..839d94930add4
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationConnection.java
@@ -0,0 +1,184 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.unsupported;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.NClob;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Struct;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.WrapperAdapter;
+
+/**
+ * 声明不支持操作的数据库连接对象.
+ *
+ * @author zhangliang
+ */
+public abstract class AbstractUnsupportedOperationConnection extends WrapperAdapter implements Connection {
+
+ @Override
+ public final CallableStatement prepareCall(final String sql) throws SQLException {
+ throw new SQLFeatureNotSupportedException("prepareCall");
+ }
+
+ @Override
+ public final CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException {
+ throw new SQLFeatureNotSupportedException("prepareCall");
+ }
+
+ @Override
+ public final CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException {
+ throw new SQLFeatureNotSupportedException("prepareCall");
+ }
+
+ @Override
+ public final String nativeSQL(final String sql) throws SQLException {
+ throw new SQLFeatureNotSupportedException("nativeSQL");
+ }
+
+ @Override
+ public final Savepoint setSavepoint() throws SQLException {
+ throw new SQLFeatureNotSupportedException("setSavepoint");
+ }
+
+ @Override
+ public final Savepoint setSavepoint(final String name) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setSavepoint name");
+ }
+
+ @Override
+ public final void releaseSavepoint(final Savepoint savepoint) throws SQLException {
+ throw new SQLFeatureNotSupportedException("releaseSavepoint");
+ }
+
+ @Override
+ public final void rollback(final Savepoint savepoint) throws SQLException {
+ throw new SQLFeatureNotSupportedException("rollback savepoint");
+ }
+
+ @Override
+ public final void abort(final Executor executor) throws SQLException {
+ throw new SQLFeatureNotSupportedException("abort");
+ }
+
+ @Override
+ public final String getCatalog() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getCatalog");
+ }
+
+ @Override
+ public final void setCatalog(final String catalog) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setCatalog");
+ }
+
+ @Override
+ public final String getSchema() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getSchema");
+ }
+
+ @Override
+ public final void setSchema(final String schema) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setSchema");
+ }
+
+ @Override
+ public final Map> getTypeMap() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getTypeMap");
+ }
+
+ @Override
+ public final void setTypeMap(final Map> map) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setTypeMap");
+ }
+
+ @Override
+ public final int getNetworkTimeout() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getNetworkTimeout");
+ }
+
+ @Override
+ public final void setNetworkTimeout(final Executor executor, final int milliseconds) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setNetworkTimeout");
+ }
+
+ @Override
+ public final Clob createClob() throws SQLException {
+ throw new SQLFeatureNotSupportedException("createClob");
+ }
+
+ @Override
+ public final Blob createBlob() throws SQLException {
+ throw new SQLFeatureNotSupportedException("createBlob");
+ }
+
+ @Override
+ public final NClob createNClob() throws SQLException {
+ throw new SQLFeatureNotSupportedException("createNClob");
+ }
+
+ @Override
+ public final SQLXML createSQLXML() throws SQLException {
+ throw new SQLFeatureNotSupportedException("createSQLXML");
+ }
+
+ @Override
+ public final Array createArrayOf(final String typeName, final Object[] elements) throws SQLException {
+ throw new SQLFeatureNotSupportedException("createArrayOf");
+ }
+
+ @Override
+ public final Struct createStruct(final String typeName, final Object[] attributes) throws SQLException {
+ throw new SQLFeatureNotSupportedException("createStruct");
+ }
+
+ @Override
+ public final boolean isValid(final int timeout) throws SQLException {
+ throw new SQLFeatureNotSupportedException("isValid");
+ }
+
+ @Override
+ public final Properties getClientInfo() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getClientInfo");
+ }
+
+ @Override
+ public final String getClientInfo(final String name) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getClientInfo name");
+ }
+
+ @Override
+ public final void setClientInfo(final String name, final String value) throws SQLClientInfoException {
+ throw new UnsupportedOperationException("setClientInfo name value");
+ }
+
+ @Override
+ public final void setClientInfo(final Properties properties) throws SQLClientInfoException {
+ throw new UnsupportedOperationException("setClientInfo properties");
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationDataSource.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationDataSource.java
new file mode 100644
index 0000000000000..a62d3fe3f6421
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationDataSource.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.unsupported;
+
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+
+import javax.sql.DataSource;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.WrapperAdapter;
+
+/**
+ * 声明不支持操作的数据源对象.
+ *
+ * @author zhangliang
+ */
+public abstract class AbstractUnsupportedOperationDataSource extends WrapperAdapter implements DataSource {
+
+ @Override
+ public final int getLoginTimeout() throws SQLException {
+ throw new SQLFeatureNotSupportedException("unsupported getLoginTimeout()");
+ }
+
+ @Override
+ public final void setLoginTimeout(final int seconds) throws SQLException {
+ throw new SQLFeatureNotSupportedException("unsupported setLoginTimeout(int seconds)");
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationPreparedStatement.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationPreparedStatement.java
new file mode 100644
index 0000000000000..d6581cc295827
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationPreparedStatement.java
@@ -0,0 +1,95 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.unsupported;
+
+import java.io.Reader;
+import java.sql.Array;
+import java.sql.NClob;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection;
+import com.dangdang.ddframe.rdb.sharding.jdbc.ShardingStatement;
+import com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine;
+
+/**
+ * 声明不支持操作的预编译语句对象.
+ *
+ * @author zhangliang
+ */
+public abstract class AbstractUnsupportedOperationPreparedStatement extends ShardingStatement implements PreparedStatement {
+
+ public AbstractUnsupportedOperationPreparedStatement(final SQLRouteEngine sqlRouteEngine, final ShardingConnection shardingConnection,
+ final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException {
+ super(sqlRouteEngine, shardingConnection, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ @Override
+ public final ResultSetMetaData getMetaData() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getMetaData");
+ }
+
+ @Override
+ public final ParameterMetaData getParameterMetaData() throws SQLException {
+ throw new SQLFeatureNotSupportedException("ParameterMetaData");
+ }
+
+ @Override
+ public final void setNString(final int parameterIndex, final String x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setNString");
+ }
+
+ @Override
+ public final void setNClob(final int parameterIndex, final NClob x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setNClob");
+ }
+
+ @Override
+ public final void setNClob(final int parameterIndex, final Reader x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setNClob");
+ }
+
+ @Override
+ public final void setNClob(final int parameterIndex, final Reader x, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setNClob");
+ }
+
+ @Override
+ public final void setNCharacterStream(final int parameterIndex, final Reader x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setNCharacterStream");
+ }
+
+ @Override
+ public final void setNCharacterStream(final int parameterIndex, final Reader x, final long length) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setNCharacterStream");
+ }
+
+ @Override
+ public final void setArray(final int parameterIndex, final Array x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setArray");
+ }
+
+ @Override
+ public final void setRowId(final int parameterIndex, final RowId x) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setRowId");
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java
new file mode 100644
index 0000000000000..c0230df879bfb
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java
@@ -0,0 +1,224 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.unsupported;
+
+import java.io.Reader;
+import java.sql.Array;
+import java.sql.NClob;
+import java.sql.Ref;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+
+/**
+ * 声明不支持操作的数据结果集对象.
+ *
+ * @author zhangliang
+ */
+public abstract class AbstractUnsupportedOperationResultSet extends AbstractResultSetUpdaterAdapter {
+
+ @Override
+ public final boolean previous() throws SQLException {
+ throw new SQLFeatureNotSupportedException("previous");
+ }
+
+ @Override
+ public final boolean isBeforeFirst() throws SQLException {
+ throw new SQLFeatureNotSupportedException("isBeforeFirst");
+ }
+
+ @Override
+ public final boolean isAfterLast() throws SQLException {
+ throw new SQLFeatureNotSupportedException("isAfterLast");
+ }
+
+ @Override
+ public final boolean isFirst() throws SQLException {
+ throw new SQLFeatureNotSupportedException("isFirst");
+ }
+
+ @Override
+ public final boolean isLast() throws SQLException {
+ throw new SQLFeatureNotSupportedException("isLast");
+ }
+
+ @Override
+ public final void beforeFirst() throws SQLException {
+ throw new SQLFeatureNotSupportedException("beforeFirst");
+ }
+
+ @Override
+ public final void afterLast() throws SQLException {
+ throw new SQLFeatureNotSupportedException("afterLast");
+ }
+
+ @Override
+ public final boolean first() throws SQLException {
+ throw new SQLFeatureNotSupportedException("first");
+ }
+
+ @Override
+ public final boolean last() throws SQLException {
+ throw new SQLFeatureNotSupportedException("last");
+ }
+
+ @Override
+ public final boolean absolute(final int row) throws SQLException {
+ throw new SQLFeatureNotSupportedException("absolute");
+ }
+
+ @Override
+ public final boolean relative(final int rows) throws SQLException {
+ throw new SQLFeatureNotSupportedException("relative");
+ }
+
+ @Override
+ public final int getRow() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getRow");
+ }
+
+ @Override
+ public final void insertRow() throws SQLException {
+ throw new SQLFeatureNotSupportedException("insertRow");
+ }
+
+ @Override
+ public final void updateRow() throws SQLException {
+ throw new SQLFeatureNotSupportedException("updateRow");
+ }
+
+ @Override
+ public final void deleteRow() throws SQLException {
+ throw new SQLFeatureNotSupportedException("deleteRow");
+ }
+
+ @Override
+ public final void refreshRow() throws SQLException {
+ throw new SQLFeatureNotSupportedException("refreshRow");
+ }
+
+ @Override
+ public final void cancelRowUpdates() throws SQLException {
+ throw new SQLFeatureNotSupportedException("cancelRowUpdates");
+ }
+
+ @Override
+ public final void moveToInsertRow() throws SQLException {
+ throw new SQLFeatureNotSupportedException("moveToInsertRow");
+ }
+
+ @Override
+ public final void moveToCurrentRow() throws SQLException {
+ throw new SQLFeatureNotSupportedException("moveToCurrentRow");
+ }
+
+ @Override
+ public final boolean rowInserted() throws SQLException {
+ throw new SQLFeatureNotSupportedException("rowInserted");
+ }
+
+ @Override
+ public final boolean rowUpdated() throws SQLException {
+ throw new SQLFeatureNotSupportedException("rowUpdated");
+ }
+
+ @Override
+ public final boolean rowDeleted() throws SQLException {
+ throw new SQLFeatureNotSupportedException("rowDeleted");
+ }
+
+ @Override
+ public final String getCursorName() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getCursorName");
+ }
+
+ @Override
+ public final int getHoldability() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getHoldability");
+ }
+
+ @Override
+ public final String getNString(final int columnIndex) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getNString");
+ }
+
+ @Override
+ public final String getNString(final String columnLabel) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getNString");
+ }
+
+ @Override
+ public final NClob getNClob(final int columnIndex) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getNClob");
+ }
+
+ @Override
+ public final NClob getNClob(final String columnLabel) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getNClob");
+ }
+
+ @Override
+ public final Reader getNCharacterStream(final int columnIndex) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getNCharacterStream");
+ }
+
+ @Override
+ public final Reader getNCharacterStream(final String columnLabel) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getNCharacterStream");
+ }
+
+ @Override
+ public final Ref getRef(final int columnIndex) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getRef");
+ }
+
+ @Override
+ public final Ref getRef(final String columnLabel) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getRef");
+ }
+
+ @Override
+ public final Array getArray(final int columnIndex) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getArray");
+ }
+
+ @Override
+ public final Array getArray(final String columnLabel) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getArray");
+ }
+
+ @Override
+ public final RowId getRowId(final int columnIndex) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getRowId");
+ }
+
+ @Override
+ public final RowId getRowId(final String columnLabel) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getRowId");
+ }
+
+ @Override
+ public final T getObject(final int columnIndex, final Class type) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getObject with type");
+ }
+
+ @Override
+ public final T getObject(final String columnLabel, final Class type) throws SQLException {
+ throw new SQLFeatureNotSupportedException("getObject with type");
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationStatement.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationStatement.java
new file mode 100644
index 0000000000000..fc00b7bdb7754
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/unsupported/AbstractUnsupportedOperationStatement.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.unsupported;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.Statement;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.WrapperAdapter;
+
+/**
+ * 声明不支持操作的静态语句对象.
+ *
+ * @author gaohongtao
+ */
+public abstract class AbstractUnsupportedOperationStatement extends WrapperAdapter implements Statement {
+
+ @Override
+ public final int getMaxFieldSize() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getMaxFieldSize");
+ }
+
+ @Override
+ public final void setMaxFieldSize(final int max) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setMaxFieldSize");
+ }
+
+ @Override
+ public final int getMaxRows() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getMaxRows");
+ }
+
+ @Override
+ public final void setMaxRows(final int max) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setMaxRows");
+ }
+
+ @Override
+ public final int getQueryTimeout() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getQueryTimeout");
+ }
+
+ @Override
+ public final void setQueryTimeout(final int seconds) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setQueryTimeout");
+ }
+
+ @Override
+ public final int getFetchDirection() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getFetchDirection");
+ }
+
+ @Override
+ public final void setFetchDirection(final int direction) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setFetchDirection");
+ }
+
+ @Override
+ public final ResultSet getGeneratedKeys() throws SQLException {
+ throw new SQLFeatureNotSupportedException("getGeneratedKeys");
+ }
+
+ @Override
+ public final void addBatch(final String sql) throws SQLException {
+ throw new SQLFeatureNotSupportedException("addBatch sql");
+ }
+
+ @Override
+ public void clearBatch() throws SQLException {
+ throw new SQLFeatureNotSupportedException("clearBatch");
+ }
+
+ @Override
+ public int[] executeBatch() throws SQLException {
+ throw new SQLFeatureNotSupportedException("executeBatch");
+ }
+
+ @Override
+ public final void closeOnCompletion() throws SQLException {
+ throw new SQLFeatureNotSupportedException("closeOnCompletion");
+ }
+
+ @Override
+ public final boolean isCloseOnCompletion() throws SQLException {
+ throw new SQLFeatureNotSupportedException("isCloseOnCompletion");
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/util/JdbcMethodInvocation.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/util/JdbcMethodInvocation.java
new file mode 100644
index 0000000000000..18f83b031b692
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/util/JdbcMethodInvocation.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.jdbc.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import com.dangdang.ddframe.rdb.sharding.exception.ShardingJdbcException;
+
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 反射调用JDBC相关方法的工具类.
+ *
+ * @author gaohongtao
+ */
+@RequiredArgsConstructor
+public final class JdbcMethodInvocation {
+
+ private final Method method;
+
+ private final Object[] arguments;
+
+ /**
+ * 调用方法.
+ *
+ * @param target 目标对象
+ */
+ public void invoke(final Object target) {
+ try {
+ method.invoke(target, arguments);
+ } catch (final IllegalAccessException | InvocationTargetException ex) {
+ throw new ShardingJdbcException("Invoke jdbc method exception", ex);
+ }
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/ResultSetFactory.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/ResultSetFactory.java
new file mode 100644
index 0000000000000..d4e5a097f7a29
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/ResultSetFactory.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+import com.dangdang.ddframe.rdb.sharding.merger.aggregation.AggregationInvokeHandler;
+import com.dangdang.ddframe.rdb.sharding.merger.aggregation.AggregationResultSet;
+import com.dangdang.ddframe.rdb.sharding.merger.groupby.GroupByInvokeHandler;
+import com.dangdang.ddframe.rdb.sharding.merger.groupby.GroupByResultSet;
+import com.dangdang.ddframe.rdb.sharding.merger.iterator.IteratorResultSet;
+import com.dangdang.ddframe.rdb.sharding.merger.orderby.OrderByResultSet;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext.ResultSetType;
+
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 创建归并分片结果集的工厂.
+ *
+ * @author gaohongtao
+ */
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+@Slf4j
+public final class ResultSetFactory {
+
+ /**
+ * 获取结果集.
+ *
+ * @param resultSets 结果集列表
+ * @param sqlParsedResult SQL解析结果
+ * @return 结果集包装
+ */
+ public static ResultSet getResultSet(final List resultSets, final MergeContext mergeContext) throws SQLException {
+ ResultSetType resultSetType = mergeContext.getResultSetType();
+ log.trace("Get '{}' result set", resultSetType);
+ switch (resultSetType) {
+ case GroupBy:
+ return createDelegateResultSet(new GroupByInvokeHandler(new GroupByResultSet(resultSets, mergeContext)));
+ case Aggregate:
+ return createDelegateResultSet(new AggregationInvokeHandler(new AggregationResultSet(resultSets, mergeContext)));
+ case OrderBy:
+ return new OrderByResultSet(resultSets, mergeContext);
+ case Iterator:
+ return new IteratorResultSet(resultSets, mergeContext);
+ default:
+ throw new UnsupportedOperationException(resultSetType.name());
+ }
+ }
+
+ private static ResultSet createDelegateResultSet(final InvocationHandler handler) {
+ return (ResultSet) Proxy.newProxyInstance(ResultSetFactory.class.getClassLoader(), new Class[]{ResultSet.class}, handler);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AbstractAggregationUnit.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AbstractAggregationUnit.java
new file mode 100644
index 0000000000000..ae03d33d02057
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AbstractAggregationUnit.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.aggregation;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetQueryIndex;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.AggregationColumn;
+
+/**
+ * 归并计算单元的抽象类.
+ *
+ * @author zhangliang
+ */
+public abstract class AbstractAggregationUnit implements AggregationUnit {
+
+ @Override
+ public final void merge(final AggregationColumn aggregationColumn, final AggregationValue aggregationValue, final ResultSetQueryIndex resultSetQueryIndex) throws SQLException {
+ if (!aggregationColumn.getDerivedColumns().isEmpty()) {
+ Collection> paramList = new ArrayList>(aggregationColumn.getDerivedColumns().size());
+ for (AggregationColumn each : aggregationColumn.getDerivedColumns()) {
+ paramList.add(aggregationValue.getValue(new ResultSetQueryIndex(each.getAlias().get())));
+ }
+ doMerge(paramList.toArray(new Comparable>[aggregationColumn.getDerivedColumns().size()]));
+ } else {
+ doMerge(aggregationValue.getValue(resultSetQueryIndex));
+ }
+ }
+
+ protected abstract void doMerge(Comparable>... values);
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AccumulationAggregationUnit.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AccumulationAggregationUnit.java
new file mode 100644
index 0000000000000..1fd2055aa8ae9
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AccumulationAggregationUnit.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.aggregation;
+
+import java.math.BigDecimal;
+
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetUtil;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 累加聚合单元.
+ *
+ * @author zhangliang
+ */
+@RequiredArgsConstructor
+@Slf4j
+public final class AccumulationAggregationUnit extends AbstractAggregationUnit {
+
+ private final Class> returnType;
+
+ private BigDecimal result = new BigDecimal(0);
+
+ @Override
+ public void doMerge(final Comparable>... values) {
+ result = result.add(new BigDecimal(values[0].toString()));
+ log.trace("Accumulation result: {}", result.toString());
+ }
+
+ @Override
+ public Comparable> getResult() {
+ return (Comparable>) ResultSetUtil.convertValue(result, returnType);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationInvokeHandler.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationInvokeHandler.java
new file mode 100644
index 0000000000000..4d3960cd906a6
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationInvokeHandler.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.aggregation;
+
+import java.lang.reflect.Method;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import com.dangdang.ddframe.rdb.sharding.merger.common.AbstractMergerInvokeHandler;
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetQueryIndex;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.AggregationColumn;
+import com.google.common.base.Optional;
+
+/**
+ * 聚合函数动态代理.
+ *
+ * @author gaohongtao, zhangliang
+ */
+public final class AggregationInvokeHandler extends AbstractMergerInvokeHandler {
+
+ public AggregationInvokeHandler(final AggregationResultSet aggregationResultSet) {
+ super(aggregationResultSet);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Object doMerge(final AggregationResultSet aggregationResultSet, final Method method, final ResultSetQueryIndex resultSetQueryIndex) throws ReflectiveOperationException, SQLException {
+ Optional aggregationColumn = findAggregationColumn(aggregationResultSet, resultSetQueryIndex);
+ if (!aggregationColumn.isPresent()) {
+ return invokeOriginal(method, resultSetQueryIndex);
+ }
+ return aggregate(aggregationResultSet, (Class>) method.getReturnType(), resultSetQueryIndex, aggregationColumn.get());
+ }
+
+ private Optional findAggregationColumn(final AggregationResultSet aggregationResultSet, final ResultSetQueryIndex resultSetQueryIndex) {
+ for (AggregationColumn each : aggregationResultSet.getAggregationColumns()) {
+ if (resultSetQueryIndex.isQueryBySequence() && each.getIndex() == resultSetQueryIndex.getQueryIndex()) {
+ return Optional.of(each);
+ } else if (each.getAlias().isPresent() && each.getAlias().get().equals(resultSetQueryIndex.getQueryName())) {
+ return Optional.of(each);
+ }
+ }
+ return Optional.absent();
+ }
+
+ private Object aggregate(final AggregationResultSet aggregationResultSet, final Class> returnType,
+ final ResultSetQueryIndex resultSetQueryIndex, final AggregationColumn aggregationColumn)
+ throws SQLException {
+ AggregationUnit unit = AggregationUnitFactory.create(aggregationColumn.getAggregationType(), returnType);
+ for (ResultSet each : aggregationResultSet.getEffectivedResultSets()) {
+ unit.merge(aggregationColumn, new ResultSetAggregationValue(each), resultSetQueryIndex);
+ }
+ return unit.getResult();
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationResultSet.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationResultSet.java
new file mode 100644
index 0000000000000..a37df8b6c0452
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationResultSet.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.aggregation;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.AbstractShardingResultSet;
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetUtil;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.AggregationColumn;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext;
+
+import lombok.Getter;
+
+/**
+ * 聚合结果集.
+ *
+ * @author gaohongtao, zhangliang
+ */
+@Getter
+public final class AggregationResultSet extends AbstractShardingResultSet {
+
+ private final Collection effectivedResultSets;
+
+ private final List aggregationColumns;
+
+ private boolean hasIndexesForAggregationColumns;
+
+ public AggregationResultSet(final List resultSets, final MergeContext mergeContext) {
+ super(resultSets, mergeContext.getLimit());
+ aggregationColumns = mergeContext.getAggregationColumns();
+ effectivedResultSets = new LinkedHashSet<>(resultSets.size());
+ }
+
+ @Override
+ public boolean nextForSharding() throws SQLException {
+ if (!hasIndexesForAggregationColumns) {
+ ResultSetUtil.fillIndexesForDerivedAggregationColumns(getResultSets().iterator().next(), aggregationColumns);
+ hasIndexesForAggregationColumns = true;
+ }
+ for (ResultSet each : getResultSets()) {
+ if (!each.next()) {
+ effectivedResultSets.remove(each);
+ continue;
+ }
+ effectivedResultSets.add(each);
+ }
+ return !effectivedResultSets.isEmpty();
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationUnit.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationUnit.java
new file mode 100644
index 0000000000000..1337d9dd59137
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationUnit.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.aggregation;
+
+import java.sql.SQLException;
+
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetQueryIndex;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.AggregationColumn;
+
+/**
+ * 归并计算单元接口.
+ *
+ * @author gaohongtao
+ */
+public interface AggregationUnit {
+
+ /**
+ * 归并聚合值.
+ *
+ * @param aggregationColumn 聚合列
+ * @param aggregationValue 聚合值
+ * @param resultSetQueryIndex 结果集查询索引
+ * @throws SQLException
+ */
+ void merge(AggregationColumn aggregationColumn, AggregationValue aggregationValue, ResultSetQueryIndex resultSetQueryIndex) throws SQLException;
+
+ /**
+ * 获取计算结果.
+ *
+ * @return 计算结果
+ */
+ Comparable> getResult();
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationUnitFactory.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationUnitFactory.java
new file mode 100644
index 0000000000000..2734888c37f0f
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationUnitFactory.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.aggregation;
+
+
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.AggregationColumn.AggregationType;
+
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 聚合函数结果集归并单元工厂.
+ *
+ * @author gaohongtao
+ */
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+public final class AggregationUnitFactory {
+
+ public static AggregationUnit create(final AggregationType type, final Class> returnType) {
+ switch (type) {
+ case MAX:
+ return new ComparableAggregationUnit(false);
+ case MIN:
+ return new ComparableAggregationUnit(true);
+ case SUM:
+ case COUNT:
+ return new AccumulationAggregationUnit(returnType);
+ case AVG:
+ return new AvgAggregationUnit(returnType);
+ default:
+ throw new UnsupportedOperationException(type.name());
+ }
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationValue.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationValue.java
new file mode 100644
index 0000000000000..c5a4484ca9309
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AggregationValue.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.aggregation;
+
+import java.sql.SQLException;
+
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetQueryIndex;
+
+/**
+ * 聚合值接口.
+ *
+ * @author zhangliang
+ */
+public interface AggregationValue {
+
+ /**
+ * 获取聚合值.
+ *
+ * @param resultSetQueryIndex 结果集查询索引.
+ * @return 聚合值
+ */
+ Comparable> getValue(ResultSetQueryIndex resultSetQueryIndex) throws SQLException;
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AvgAggregationUnit.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AvgAggregationUnit.java
new file mode 100644
index 0000000000000..f55655526acea
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/AvgAggregationUnit.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.aggregation;
+
+import java.math.BigDecimal;
+
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetUtil;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 平均值聚合单元.
+ *
+ * @author gaohongtao
+ */
+@RequiredArgsConstructor
+@Slf4j
+public class AvgAggregationUnit extends AbstractAggregationUnit {
+
+ private final Class> returnType;
+
+ private BigDecimal count = new BigDecimal(0);
+
+ private BigDecimal sum = new BigDecimal(0);
+
+ @Override
+ public void doMerge(final Comparable>... values) {
+ count = count.add(new BigDecimal(values[0].toString()));
+ sum = sum.add(new BigDecimal(values[1].toString()));
+ log.trace("AVG result COUNT: {} SUM: {}", count, sum);
+ }
+
+ @Override
+ public Comparable> getResult() {
+ // TODO 通过metadata获取数据库的浮点数精度值
+ return (Comparable>) ResultSetUtil.convertValue(sum.divide(count, 4, BigDecimal.ROUND_HALF_UP), returnType);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/ComparableAggregationUnit.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/ComparableAggregationUnit.java
new file mode 100644
index 0000000000000..6a0238ba3d3ad
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/ComparableAggregationUnit.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.aggregation;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 比较聚合单元.
+ *
+ * @author gaohongtao
+ */
+@RequiredArgsConstructor
+@Slf4j
+public final class ComparableAggregationUnit extends AbstractAggregationUnit {
+
+ private final boolean asc;
+
+ private Comparable> result;
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void doMerge(@SuppressWarnings("rawtypes") final Comparable... values) {
+ if (null == result) {
+ result = values[0];
+ log.trace("Comparable result: {}", result);
+ return;
+ }
+ int comparedValue = values[0].compareTo(result);
+ if (asc && comparedValue < 0 || !asc && comparedValue > 0) {
+ result = values[0];
+ log.trace("Comparable result: {}", result);
+ }
+ }
+
+ @Override
+ public Comparable> getResult() {
+ return result;
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/ResultSetAggregationValue.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/ResultSetAggregationValue.java
new file mode 100644
index 0000000000000..1cbda9a8bc86a
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/aggregation/ResultSetAggregationValue.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.aggregation;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetQueryIndex;
+
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+public final class ResultSetAggregationValue implements AggregationValue {
+
+ private final ResultSet resultSet;
+
+ @Override
+ public Comparable> getValue(final ResultSetQueryIndex resultSetQueryIndex) throws SQLException {
+ return resultSetQueryIndex.isQueryBySequence()
+ ? (Comparable>) resultSet.getObject(resultSetQueryIndex.getQueryIndex()) : (Comparable>) resultSet.getObject(resultSetQueryIndex.getQueryName());
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/common/AbstractMergerInvokeHandler.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/common/AbstractMergerInvokeHandler.java
new file mode 100644
index 0000000000000..ca19d5eb4c77e
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/common/AbstractMergerInvokeHandler.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.common;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.AbstractShardingResultSet;
+
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 结果归并动态代理抽象类.
+ *
+ * @author zhangliang
+ *
+ * @param 结果集类型
+ */
+@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
+public abstract class AbstractMergerInvokeHandler implements InvocationHandler {
+
+ private final T resultSet;
+
+ @Override
+ public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+ if (!isGetDataMethod(method, args)) {
+ return method.invoke(resultSet, args);
+ }
+ return doMerge(resultSet, method, new ResultSetQueryIndex(args[0]));
+ }
+
+ private boolean isGetDataMethod(final Method method, final Object[] args) {
+ return method.getName().startsWith("get") && null != args && 1 == args.length;
+ }
+
+ protected abstract Object doMerge(T resultSet, Method method, ResultSetQueryIndex resultSetQueryIndex) throws ReflectiveOperationException, SQLException;
+
+ protected Object invokeOriginal(final Method method, final ResultSetQueryIndex resultSetQueryIndex) throws ReflectiveOperationException {
+ return method.invoke(resultSet, new Object[] {resultSetQueryIndex.getRawQueryIndex()});
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/common/ResultSetQueryIndex.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/common/ResultSetQueryIndex.java
new file mode 100644
index 0000000000000..8652dfe20d437
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/common/ResultSetQueryIndex.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.common;
+
+import lombok.Getter;
+
+/**
+ * 结果集查询索引.
+ *
+ *
+ * 用于查询结果集.
+ * 如果索引类型是int, 表示根据序号查询, 从1开始.
+ * 如果索引类型是String, 表示根据字段返回值名称查询.
+ *
+ *
+ * @author zhangliang
+ */
+@Getter
+public final class ResultSetQueryIndex {
+
+ private static final int NO_INDEX = -1;
+
+ private final int queryIndex;
+
+ private final String queryName;
+
+ public ResultSetQueryIndex(final Object queryParam) {
+ if (queryParam instanceof Integer) {
+ queryIndex = (int) queryParam;
+ queryName = null;
+ } else if (queryParam instanceof String) {
+ queryIndex = NO_INDEX;
+ queryName = queryParam.toString();
+ } else {
+ throw new IllegalArgumentException(queryParam.getClass().getName());
+ }
+ }
+
+ /**
+ * 获取是否通过序号查询.
+ *
+ * @return 通过序号查询返回true, 通过名称查询返回false
+ */
+ public boolean isQueryBySequence() {
+ return NO_INDEX != queryIndex;
+ }
+
+ /**
+ * 忽略类型获取查询索引.
+ *
+ * @return 查询索引
+ */
+ public Object getRawQueryIndex() {
+ return isQueryBySequence() ? queryIndex : queryName;
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/common/ResultSetUtil.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/common/ResultSetUtil.java
new file mode 100644
index 0000000000000..d342255567fae
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/common/ResultSetUtil.java
@@ -0,0 +1,155 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.common;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+
+import com.dangdang.ddframe.rdb.sharding.exception.ShardingJdbcException;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.AggregationColumn;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.GroupByColumn;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.OrderByColumn;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.OrderByColumn.OrderByType;
+import com.google.common.base.Preconditions;
+
+import lombok.AccessLevel;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 结果集处理工具类.
+ *
+ * @author gaohongtao
+ */
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+public final class ResultSetUtil {
+
+ /**
+ * 从结果集中提取结果值.
+ *
+ * @param groupByColumn 分组列对象
+ * @param resultSet 目标结果集
+ * @return 结果对象
+ * @throws SQLException
+ */
+ public static Object getValue(final GroupByColumn groupByColumn, final ResultSet resultSet) throws SQLException {
+ Object result = getValue(groupByColumn.getAlias(), resultSet);
+ Preconditions.checkNotNull(result);
+ return result;
+ }
+
+ /**
+ * 从结果集中提取结果值.
+ *
+ * @param orderByColumn 排序列对象
+ * @param resultSet 目标结果集
+ * @return 结果对象
+ * @throws SQLException
+ */
+ public static Object getValue(final OrderByColumn orderByColumn, final ResultSet resultSet) throws SQLException {
+ Object result;
+ if (orderByColumn.getIndex().isPresent()) {
+ result = resultSet.getObject(orderByColumn.getIndex().get());
+ } else {
+ result = getValue(orderByColumn.getName().get(), resultSet);
+ }
+ Preconditions.checkNotNull(result);
+ return result;
+ }
+
+ private static Object getValue(final String columnName, final ResultSet resultSet) throws SQLException {
+ Object result = resultSet.getObject(columnName);
+ if (null == result) {
+ result = resultSet.getObject(columnName.toUpperCase());
+ }
+ if (null == result) {
+ result = resultSet.getObject(columnName.toLowerCase());
+ }
+ return result;
+ }
+
+ /**
+ * 根据返回值类型返回特定类型的结果.
+ *
+ * @param value 原始结果
+ * @param convertType 返回值类型
+ * @return 特定类型的返回结果
+ */
+ public static Object convertValue(final Object value, final Class> convertType) {
+ if (value instanceof Number) {
+ return convertNumberValue(value, convertType);
+ } else {
+ if (String.class.equals(convertType)) {
+ return value.toString();
+ } else {
+ return value;
+ }
+ }
+ }
+
+ private static Object convertNumberValue(final Object value, final Class> convertType) {
+ Number number = (Number) value;
+ switch (convertType.getName()) {
+ case "int":
+ return number.intValue();
+ case "long":
+ return number.longValue();
+ case "double":
+ return number.doubleValue();
+ case "float":
+ return number.floatValue();
+ case "java.math.BigDecimal":
+ if (number instanceof BigDecimal) {
+ return number;
+ } else {
+ return new BigDecimal(number.toString());
+ }
+ default:
+ throw new ShardingJdbcException("Unsupported data type:%s", convertType);
+ }
+ }
+
+ /**
+ * 根据排序类型比较大小.
+ *
+ * @param thisValue 待比较的值
+ * @param otherValue 待比较的值
+ * @param orderByType 排序类型
+ * @return 负数,零和正数分别表示小于,等于和大于
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public static int compareTo(final Comparable thisValue, final Comparable otherValue, final OrderByType orderByType) {
+ return OrderByType.ASC == orderByType ? thisValue.compareTo(otherValue) : -thisValue.compareTo(otherValue);
+ }
+
+ /**
+ * 向聚合列的补列填充索引值.
+ *
+ * @param resultSet 结果集对象
+ * @param aggregationColumns 聚合列集合
+ * @throws SQLException SQL异常
+ */
+ public static void fillIndexesForDerivedAggregationColumns(final ResultSet resultSet, final Collection aggregationColumns) throws SQLException {
+ for (AggregationColumn aggregationColumn : aggregationColumns) {
+ for (AggregationColumn derivedColumn : aggregationColumn.getDerivedColumns()) {
+ derivedColumn.setIndex(resultSet.findColumn(derivedColumn.getAlias().get()));
+ }
+ }
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByInvokeHandler.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByInvokeHandler.java
new file mode 100644
index 0000000000000..8c29abeda3d3c
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByInvokeHandler.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.groupby;
+
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+
+import com.dangdang.ddframe.rdb.sharding.merger.common.AbstractMergerInvokeHandler;
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetQueryIndex;
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetUtil;
+
+/**
+ * 分组函数动态代理.
+ *
+ * @author gaohongtao
+ */
+public class GroupByInvokeHandler extends AbstractMergerInvokeHandler {
+
+ public GroupByInvokeHandler(final GroupByResultSet groupByResultSet) {
+ super(groupByResultSet);
+ }
+
+ @Override
+ protected Object doMerge(final GroupByResultSet groupByResultSet, final Method method, final ResultSetQueryIndex resultSetQueryIndex) throws ReflectiveOperationException, SQLException {
+ // TODO 更新文档:The column is not aggregation function, get first result set
+ return ResultSetUtil.convertValue(groupByResultSet.getCurrentGroupByResultSet().getValue(resultSetQueryIndex), method.getReturnType());
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByKey.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByKey.java
new file mode 100644
index 0000000000000..93eba5f61b850
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByKey.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.groupby;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+/**
+ * 分组结果集数据存储索引.
+ *
+ * @author gaohongtao, zhangliang
+ */
+@EqualsAndHashCode
+@ToString
+public final class GroupByKey {
+
+ private final List unionKey = new ArrayList<>();
+
+ public void append(final String key) {
+ unionKey.add(key);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByResultSet.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByResultSet.java
new file mode 100644
index 0000000000000..9dc0bae3c87c5
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByResultSet.java
@@ -0,0 +1,194 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.groupby;
+
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import com.dangdang.ddframe.rdb.sharding.executor.ExecuteUnit;
+import com.dangdang.ddframe.rdb.sharding.executor.ExecutorEngine;
+import com.dangdang.ddframe.rdb.sharding.executor.MergeUnit;
+import com.dangdang.ddframe.rdb.sharding.jdbc.AbstractShardingResultSet;
+import com.dangdang.ddframe.rdb.sharding.merger.aggregation.AggregationUnit;
+import com.dangdang.ddframe.rdb.sharding.merger.aggregation.AggregationUnitFactory;
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetQueryIndex;
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetUtil;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.AggregationColumn;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.GroupByColumn;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.OrderByColumn;
+import com.google.common.base.Optional;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 分组结果集.
+ *
+ *
+ * 采用map-reduce的方式.
+ * map-reduce过程发生在nextForSharding()方法第一次被调用的时候, 将相同group-key的结果集放在一起,并同时做order by的排序处理(相当于shuffle过程).
+ *
+ *
+ * @author gaohongtao, zhangliang
+ */
+@Slf4j
+public final class GroupByResultSet extends AbstractShardingResultSet {
+
+ private final List groupByColumns;
+
+ private final List orderByColumns;
+
+ private final List aggregationColumns;
+
+ private final ResultSetMetaData resultSetMetaData;
+
+ private final List columnLabels;
+
+ private Iterator groupByResultIterator;
+
+ @Getter(AccessLevel.PROTECTED)
+ private GroupByValue currentGroupByResultSet;
+
+ public GroupByResultSet(final List resultSets, final MergeContext mergeContext) throws SQLException {
+ super(resultSets, mergeContext.getLimit());
+ groupByColumns = mergeContext.getGroupByColumns();
+ orderByColumns = mergeContext.getOrderByColumns();
+ aggregationColumns = mergeContext.getAggregationColumns();
+ resultSetMetaData = getResultSets().iterator().next().getMetaData();
+ columnLabels = new ArrayList<>(resultSetMetaData.getColumnCount());
+ fillRelatedColumnNames();
+ }
+
+ private void fillRelatedColumnNames() throws SQLException {
+ for (int i = 1; i < resultSetMetaData.getColumnCount() + 1; i++) {
+ columnLabels.add(resultSetMetaData.getColumnLabel(i));
+ }
+ }
+
+ @Override
+ protected boolean nextForSharding() throws SQLException {
+ if (null == groupByResultIterator) {
+ ResultSetUtil.fillIndexesForDerivedAggregationColumns(getResultSets().iterator().next(), aggregationColumns);
+ groupByResultIterator = reduce(map()).iterator();
+ }
+ if (groupByResultIterator.hasNext()) {
+ currentGroupByResultSet = groupByResultIterator.next();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private Multimap map() throws SQLException {
+ ExecuteUnit> executeUnit = new ExecuteUnit>() {
+
+ @Override
+ public Map execute(final ResultSet resultSet) throws SQLException {
+ // TODO 应该可以根据limit判断result的初始size,避免size满了重分配
+ Map result = new HashMap<>();
+ while (resultSet.next()) {
+ GroupByValue groupByValue = new GroupByValue();
+ for (int count = 1; count <= columnLabels.size(); count++) {
+ groupByValue.put(count, resultSetMetaData.getColumnLabel(count), (Comparable>) resultSet.getObject(count));
+ }
+ GroupByKey groupByKey = new GroupByKey();
+ for (GroupByColumn each : groupByColumns) {
+ groupByKey.append(ResultSetUtil.getValue(each, resultSet).toString());
+ }
+ result.put(groupByKey, groupByValue);
+ }
+ log.trace("Result set mapping: {}", result);
+ return result;
+ }
+ };
+ MergeUnit, Multimap> mergeUnit = new MergeUnit, Multimap>() {
+
+ @Override
+ public Multimap merge(final List> values) {
+ Multimap result = HashMultimap.create();
+ for (Map each : values) {
+ for (Entry entry : each.entrySet()) {
+ result.put(entry.getKey(), entry.getValue());
+ }
+ }
+ return result;
+ }
+ };
+ Multimap result = ExecutorEngine.execute(getResultSets(), executeUnit, mergeUnit);
+ log.trace("Mapped result: {}", result);
+ return result;
+ }
+
+ private Collection reduce(final Multimap mappedResult) throws SQLException {
+ List result = new ArrayList<>(mappedResult.values().size() * columnLabels.size());
+ for (GroupByKey key : mappedResult.keySet()) {
+ Collection each = mappedResult.get(key);
+ GroupByValue reduceResult = new GroupByValue();
+ for (int i = 0; i < columnLabels.size(); i++) {
+ int index = i + 1;
+ Optional aggregationColumn = findAggregationColumn(index);
+ Comparable> value = null;
+ if (aggregationColumn.isPresent()) {
+ value = aggregate(aggregationColumn.get(), index, each);
+ }
+ value = null == value ? each.iterator().next().getValue(new ResultSetQueryIndex(index)) : value;
+ reduceResult.put(index, columnLabels.get(i), value);
+ }
+ if (orderByColumns.isEmpty()) {
+ reduceResult.addGroupByColumns(groupByColumns);
+ } else {
+ reduceResult.addOrderColumns(orderByColumns);
+ }
+ result.add(reduceResult);
+ }
+ Collections.sort(result);
+ log.trace("Reduced result: {}", result);
+ return result;
+ }
+
+ private Optional findAggregationColumn(final int index) {
+ for (AggregationColumn each : aggregationColumns) {
+ if (each.getIndex() == index) {
+ return Optional.of(each);
+ }
+ }
+ return Optional.absent();
+ }
+
+ private Comparable> aggregate(final AggregationColumn column, final int index, final Collection groupByValues) throws SQLException {
+ AggregationUnit unit = AggregationUnitFactory.create(column.getAggregationType(), BigDecimal.class);
+ for (GroupByValue each : groupByValues) {
+ unit.merge(column, each, new ResultSetQueryIndex(index));
+ }
+ return unit.getResult();
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByValue.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByValue.java
new file mode 100644
index 0000000000000..f4793a9e7a275
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/groupby/GroupByValue.java
@@ -0,0 +1,114 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.groupby;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections4.map.CaseInsensitiveMap;
+
+import com.dangdang.ddframe.rdb.sharding.merger.aggregation.AggregationValue;
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetQueryIndex;
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetUtil;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.GroupByColumn;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.OrderByColumn;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.OrderByColumn.OrderByType;
+
+import lombok.ToString;
+
+/**
+ * 分组结果集数据存储对象.
+ *
+ * @author gaohongtao, zhangliang
+ */
+@ToString
+public class GroupByValue implements AggregationValue, Comparable {
+
+ private final Map> indexMap = new LinkedHashMap<>();
+
+ private final CaseInsensitiveMap> columnLabelMap = new CaseInsensitiveMap<>();
+
+ private final List orderColumns = new ArrayList<>();
+
+ private final List groupByColumns = new ArrayList<>();
+
+ public void put(final int index, final String columnName, final Comparable> value) {
+ if (!indexMap.containsKey(index)) {
+ indexMap.put(index, value);
+ }
+ if (!columnLabelMap.containsKey(columnName)) {
+ columnLabelMap.put(columnName, value);
+ }
+ }
+
+ @Override
+ public Comparable> getValue(final ResultSetQueryIndex resultSetQueryIndex) {
+ return resultSetQueryIndex.isQueryBySequence() ? indexMap.get(resultSetQueryIndex.getQueryIndex()) : columnLabelMap.get(resultSetQueryIndex.getQueryName());
+ }
+
+ public void addGroupByColumns(final List columns) {
+ groupByColumns.addAll(columns);
+ }
+
+ public void addOrderColumns(final List columns) {
+ orderColumns.addAll(columns);
+ }
+
+ @Override
+ public int compareTo(final GroupByValue other) {
+ if (null == other) {
+ return -1;
+ }
+ if (orderColumns.isEmpty()) {
+ return compareFromGroupByColumns(other);
+ }
+ return compareFromOrderByColumns(other);
+ }
+
+ private int compareFromGroupByColumns(final GroupByValue other) {
+ for (GroupByColumn each : groupByColumns) {
+ int result = ResultSetUtil.compareTo(columnLabelMap.get(each.getAlias()), other.columnLabelMap.get(each.getAlias()), each.getOrderByType());
+ if (0 != result) {
+ return result;
+ }
+ }
+ return 0;
+ }
+
+ private int compareFromOrderByColumns(final GroupByValue other) {
+ for (OrderByColumn each : orderColumns) {
+ OrderByType orderByType = null == each.getOrderByType() ? OrderByType.ASC : each.getOrderByType();
+ Comparable> thisValue;
+ Comparable> otherValue;
+ if (each.getName().isPresent()) {
+ thisValue = columnLabelMap.get(each.getName().get());
+ otherValue = other.columnLabelMap.get(each.getName().get());
+ } else {
+ thisValue = indexMap.get(each.getIndex().get());
+ otherValue = other.indexMap.get(each.getIndex().get());
+ }
+ int result = ResultSetUtil.compareTo(thisValue, otherValue, orderByType);
+ if (0 != result) {
+ return result;
+ }
+ }
+ return 0;
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/iterator/IteratorResultSet.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/iterator/IteratorResultSet.java
new file mode 100644
index 0000000000000..1542a351e07d0
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/iterator/IteratorResultSet.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.iterator;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.AbstractShardingResultSet;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext;
+
+/**
+ * 迭代结果集.
+ *
+ * @author zhangliang
+ */
+public final class IteratorResultSet extends AbstractShardingResultSet {
+
+ public IteratorResultSet(final List resultSets, final MergeContext mergeContext) {
+ super(resultSets, mergeContext.getLimit());
+ }
+
+ @Override
+ protected boolean nextForSharding() throws SQLException {
+ if (getCurrentResultSet().next()) {
+ return true;
+ }
+ for (int i = getResultSets().indexOf(getCurrentResultSet()) + 1; i < getResultSets().size(); i++) {
+ ResultSet each = getResultSets().get(i);
+ if (each.next()) {
+ setCurrentResultSet(each);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/orderby/OrderByResultSet.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/orderby/OrderByResultSet.java
new file mode 100644
index 0000000000000..e8d93128ad133
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/orderby/OrderByResultSet.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.orderby;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.dangdang.ddframe.rdb.sharding.jdbc.AbstractShardingResultSet;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.OrderByColumn;
+
+/**
+ * 排序结果集处理.
+ *
+ * @author gaohongtao, zhangliang
+ */
+public final class OrderByResultSet extends AbstractShardingResultSet {
+
+ private final List orderByColumns;
+
+ private final List effectivedResultSets;
+
+ private boolean initial;
+
+ public OrderByResultSet(final List resultSets, final MergeContext mergeContext) {
+ super(resultSets, mergeContext.getLimit());
+ orderByColumns = mergeContext.getOrderByColumns();
+ effectivedResultSets = new ArrayList<>(resultSets.size());
+ }
+
+ @Override
+ public boolean nextForSharding() throws SQLException {
+ if (!initial) {
+ initialEffectivedResultSets();
+ } else {
+ nextEffectivedResultSets();
+ }
+ OrderByValue choosenOrderByValue = null;
+ for (ResultSet each : effectivedResultSets) {
+ OrderByValue eachOrderByValue = new OrderByValue(orderByColumns, each);
+ if (null == choosenOrderByValue || choosenOrderByValue.compareTo(eachOrderByValue) > 0) {
+ choosenOrderByValue = eachOrderByValue;
+ setCurrentResultSet(each);
+ }
+ }
+ return !effectivedResultSets.isEmpty();
+ }
+
+ private void initialEffectivedResultSets() throws SQLException {
+ for (ResultSet each : getResultSets()) {
+ if (each.next()) {
+ effectivedResultSets.add(each);
+ }
+ }
+ initial = true;
+ }
+
+ private void nextEffectivedResultSets() throws SQLException {
+ boolean next = getCurrentResultSet().next();
+ if (!next) {
+ effectivedResultSets.remove(getCurrentResultSet());
+ }
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/orderby/OrderByValue.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/orderby/OrderByValue.java
new file mode 100644
index 0000000000000..5b9a995a3428e
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/merger/orderby/OrderByValue.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.merger.orderby;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.dangdang.ddframe.rdb.sharding.merger.common.ResultSetUtil;
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.OrderByColumn;
+import com.google.common.base.Preconditions;
+
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 基于结果集的排序对象.
+ *
+ * @author zhangliang
+ */
+public final class OrderByValue implements Comparable {
+
+ private final List orderByColumns;
+
+ private final Value orderByValue;
+
+ public OrderByValue(final List orderByColumns, final ResultSet resultSet) throws SQLException {
+ this.orderByColumns = orderByColumns;
+ orderByValue = new Value(orderByColumns, getValues(resultSet));
+ }
+
+ private List> getValues(final ResultSet resultSet) throws SQLException {
+ List> result = new ArrayList<>(orderByColumns.size());
+ for (OrderByColumn each : orderByColumns) {
+ Object value = ResultSetUtil.getValue(each, resultSet);
+ Preconditions.checkState(value instanceof Comparable, "Sharding-JDBC: order by value must extends Comparable");
+ result.add((Comparable>) value);
+ }
+ return result;
+ }
+
+ @Override
+ public int compareTo(final OrderByValue otherOrderByValue) {
+ return orderByValue.compareTo(otherOrderByValue.orderByValue);
+ }
+
+ @RequiredArgsConstructor
+ static final class Value implements Comparable {
+
+ private final List orderByColumns;
+
+ private final List> values;
+
+ @Override
+ public int compareTo(final Value otherOrderByValue) {
+ for (int i = 0; i < orderByColumns.size(); i++) {
+ OrderByColumn thisOrderByColumn = orderByColumns.get(i);
+ int result = ResultSetUtil.compareTo(values.get(i), otherOrderByValue.values.get(i), thisOrderByColumn.getOrderByType());
+ if (0 != result) {
+ return result;
+ }
+ }
+ return 0;
+ }
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/metrics/MetricsContext.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/metrics/MetricsContext.java
new file mode 100644
index 0000000000000..8ec4a59bc95c7
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/metrics/MetricsContext.java
@@ -0,0 +1,87 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.metrics;
+
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.LoggerFactory;
+
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Slf4jReporter;
+import com.codahale.metrics.Slf4jReporter.LoggingLevel;
+import com.codahale.metrics.Timer.Context;
+import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
+
+/**
+ * 度量工具上下文.
+ *
+ * @author gaohongtao
+ */
+public final class MetricsContext {
+
+ private static final ThreadLocal CONTEXT = new ThreadLocal<>();
+
+ private final Optional metricRegistry;
+
+ public MetricsContext(final boolean enable, final long period, final String packageName) {
+ if (enable) {
+ metricRegistry = Optional.of(new MetricRegistry());
+ Slf4jReporter reporter = Slf4jReporter.forRegistry(metricRegistry.get())
+ .outputTo(LoggerFactory.getLogger(packageName))
+ .convertRatesTo(TimeUnit.SECONDS)
+ .convertDurationsTo(TimeUnit.MILLISECONDS)
+ .withLoggingLevel(LoggingLevel.DEBUG)
+ .build();
+ reporter.start(period, TimeUnit.SECONDS);
+ } else {
+ metricRegistry = Optional.absent();
+ }
+ }
+
+ /**
+ * 注册度量上下文.
+ */
+ public void register() {
+ if (metricRegistry.isPresent() && !this.equals(CONTEXT.get())) {
+ CONTEXT.set(this);
+ }
+ }
+
+ /**
+ * 开始计时.
+ *
+ * @param name 度量目标名称
+ *
+ * @return 计时上下文
+ */
+ public static Context start(final String... name) {
+ return null == CONTEXT.get() ? null : CONTEXT.get().metricRegistry.get().timer(MetricRegistry.name(Joiner.on("-").join(name))).time();
+ }
+
+ /**
+ * 停止计时.
+ *
+ * @param context 计时上下文
+ */
+ public static void stop(final Context context) {
+ if (null != context) {
+ context.stop();
+ }
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/SQLParseEngine.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/SQLParseEngine.java
new file mode 100644
index 0000000000000..45c16ad1f5923
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/SQLParseEngine.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.parser;
+
+import java.util.Collection;
+import java.util.List;
+
+import com.alibaba.druid.sql.ast.SQLStatement;
+import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
+import com.dangdang.ddframe.rdb.sharding.parser.result.SQLParsedResult;
+import com.dangdang.ddframe.rdb.sharding.parser.visitor.SQLVisitor;
+import com.dangdang.ddframe.rdb.sharding.parser.visitor.or.OrParser;
+import com.google.common.base.Preconditions;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 不包含OR语句的SQL构建器解析.
+ *
+ * @author gaohongtao, zhangliang
+ */
+@RequiredArgsConstructor
+@Slf4j
+public final class SQLParseEngine {
+
+ private final SQLStatement sqlStatement;
+
+ private final List parameters;
+
+ private final SQLASTOutputVisitor visitor;
+
+ private final Collection shardingColumns;
+
+ /**
+ * 解析SQL.
+ *
+ * @return SQL解析结果
+ */
+ public SQLParsedResult parse() {
+ Preconditions.checkArgument(visitor instanceof SQLVisitor);
+ SQLVisitor sqlVisitor = (SQLVisitor) visitor;
+ visitor.setParameters(parameters);
+ sqlVisitor.getParseContext().setShardingColumns(shardingColumns);
+ sqlStatement.accept(visitor);
+ SQLParsedResult result;
+ if (sqlVisitor.getParseContext().isHasOrCondition()) {
+ result = new OrParser(sqlStatement, visitor).parse();
+ } else {
+ sqlVisitor.getParseContext().mergeCurrentConditionContext();
+ result = sqlVisitor.getParseContext().getParsedResult();
+ }
+ log.debug("Parsed SQL result: {}", result);
+ log.debug("Parsed SQL: {}", sqlVisitor.getSQLBuilder());
+ result.getRouteContext().setSqlBuilder(sqlVisitor.getSQLBuilder());
+ return result;
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/SQLParserFactory.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/SQLParserFactory.java
new file mode 100644
index 0000000000000..3bca79ef69b0f
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/SQLParserFactory.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.parser;
+
+import java.util.Collection;
+import java.util.List;
+
+import com.alibaba.druid.sql.ast.SQLStatement;
+import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
+import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
+import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
+import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
+import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser;
+import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
+import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
+import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser;
+import com.alibaba.druid.sql.parser.SQLStatementParser;
+import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
+import com.dangdang.ddframe.rdb.sharding.api.DatabaseType;
+import com.dangdang.ddframe.rdb.sharding.exception.SQLParserException;
+import com.dangdang.ddframe.rdb.sharding.parser.visitor.VisitorLogProxy;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * SQL解析器工厂.
+ *
+ * @author gaohongtao, zhangliang
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+@Slf4j
+public final class SQLParserFactory {
+
+ /**
+ * 创建解析器引擎对象.
+ *
+ * @param databaseType 数据库类型
+ * @param sql SQL语句
+ * @param parameters SQL中参数的值
+ * @param shardingColumns 分片列名称集合
+ * @return 解析器引擎对象
+ * @throws SQLParserException SQL解析异常
+ */
+ public static SQLParseEngine create(final DatabaseType databaseType, final String sql, final List parameters, final Collection shardingColumns) throws SQLParserException {
+ log.debug("Logic SQL: {}", sql);
+ SQLStatement sqlStatement = getSQLStatementParser(databaseType, sql).parseStatement();
+ log.trace("Get {} SQL Statement", sqlStatement.getClass().getName());
+ return new SQLParseEngine(sqlStatement, parameters, getSQLVisitor(databaseType, sqlStatement), shardingColumns);
+ }
+
+ private static SQLStatementParser getSQLStatementParser(final DatabaseType databaseType, final String sql) {
+ switch (databaseType) {
+ case H2:
+ case MySQL:
+ return new MySqlStatementParser(sql);
+ case Oracle:
+ return new OracleStatementParser(sql);
+ case SQLServer:
+ return new SQLServerStatementParser(sql);
+ case DB2:
+ return new DB2StatementParser(sql);
+ default:
+ throw new UnsupportedOperationException(String.format("Cannot support database type [%s]", databaseType));
+ }
+ }
+
+ private static SQLASTOutputVisitor getSQLVisitor(final DatabaseType databaseType, final SQLStatement sqlStatement) {
+ if (sqlStatement instanceof SQLSelectStatement) {
+ return VisitorLogProxy.enhance(SQLVisitorRegistry.getSelectVistor(databaseType));
+ }
+ if (sqlStatement instanceof SQLInsertStatement) {
+ return VisitorLogProxy.enhance(SQLVisitorRegistry.getInsertVistor(databaseType));
+ }
+ if (sqlStatement instanceof SQLUpdateStatement) {
+ return VisitorLogProxy.enhance(SQLVisitorRegistry.getUpdateVistor(databaseType));
+ }
+ if (sqlStatement instanceof SQLDeleteStatement) {
+ return VisitorLogProxy.enhance(SQLVisitorRegistry.getDeleteVistor(databaseType));
+ }
+ throw new SQLParserException("Unsupported SQL statement: [%s]", sqlStatement);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/SQLVisitorRegistry.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/SQLVisitorRegistry.java
new file mode 100644
index 0000000000000..66e91c8acd9db
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/SQLVisitorRegistry.java
@@ -0,0 +1,127 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.parser;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
+import com.dangdang.ddframe.rdb.sharding.api.DatabaseType;
+import com.dangdang.ddframe.rdb.sharding.exception.DatabaseTypeUnsupportedException;
+import com.dangdang.ddframe.rdb.sharding.parser.visitor.basic.mysql.MySQLDeleteVisitor;
+import com.dangdang.ddframe.rdb.sharding.parser.visitor.basic.mysql.MySQLInsertVisitor;
+import com.dangdang.ddframe.rdb.sharding.parser.visitor.basic.mysql.MySQLSelectVisitor;
+import com.dangdang.ddframe.rdb.sharding.parser.visitor.basic.mysql.MySQLUpdateVisitor;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+/**
+ * SQL访问器注册表.
+ *
+ * @author zhangliang
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class SQLVisitorRegistry {
+
+ private static final Map> SELECT_REGISTRY = new HashMap<>(DatabaseType.values().length);
+
+ private static final Map> INSERT_REGISTRY = new HashMap<>(DatabaseType.values().length);
+
+ private static final Map> UPDATE_REGISTRY = new HashMap<>(DatabaseType.values().length);
+
+ private static final Map> DELETE_REGISTRY = new HashMap<>(DatabaseType.values().length);
+
+ static {
+ registerSelectVistor();
+ registerInsertVistor();
+ registerUpdateVistor();
+ registerDeleteVistor();
+ }
+
+ private static void registerSelectVistor() {
+ SELECT_REGISTRY.put(DatabaseType.H2, MySQLSelectVisitor.class);
+ SELECT_REGISTRY.put(DatabaseType.MySQL, MySQLSelectVisitor.class);
+ // TODO 其他数据库
+ }
+
+ private static void registerInsertVistor() {
+ INSERT_REGISTRY.put(DatabaseType.H2, MySQLInsertVisitor.class);
+ INSERT_REGISTRY.put(DatabaseType.MySQL, MySQLInsertVisitor.class);
+ // TODO 其他数据库
+ }
+
+ private static void registerUpdateVistor() {
+ UPDATE_REGISTRY.put(DatabaseType.H2, MySQLUpdateVisitor.class);
+ UPDATE_REGISTRY.put(DatabaseType.MySQL, MySQLUpdateVisitor.class);
+ // TODO 其他数据库
+ }
+
+ private static void registerDeleteVistor() {
+ DELETE_REGISTRY.put(DatabaseType.H2, MySQLDeleteVisitor.class);
+ DELETE_REGISTRY.put(DatabaseType.MySQL, MySQLDeleteVisitor.class);
+ // TODO 其他数据库
+ }
+
+ /**
+ * 获取SELECT访问器.
+ *
+ * @param databaseType 数据库类型
+ * @return SELECT访问器
+ */
+ public static Class extends SQLASTOutputVisitor> getSelectVistor(final DatabaseType databaseType) {
+ return getVistor(databaseType, SELECT_REGISTRY);
+ }
+
+ /**
+ * 获取INSERT访问器.
+ *
+ * @param databaseType 数据库类型
+ * @return INSERT访问器
+ */
+ public static Class extends SQLASTOutputVisitor> getInsertVistor(final DatabaseType databaseType) {
+ return getVistor(databaseType, INSERT_REGISTRY);
+ }
+
+ /**
+ * 获取UPDATE访问器.
+ *
+ * @param databaseType 数据库类型
+ * @return UPDATE访问器
+ */
+ public static Class extends SQLASTOutputVisitor> getUpdateVistor(final DatabaseType databaseType) {
+ return getVistor(databaseType, UPDATE_REGISTRY);
+ }
+
+ /**
+ * 获取DELETE访问器.
+ *
+ * @param databaseType 数据库类型
+ * @return DELETE访问器
+ */
+ public static Class extends SQLASTOutputVisitor> getDeleteVistor(final DatabaseType databaseType) {
+ return getVistor(databaseType, DELETE_REGISTRY);
+ }
+
+ private static Class extends SQLASTOutputVisitor> getVistor(final DatabaseType databaseType, final Map> registry) {
+ if (!registry.containsKey(databaseType)) {
+ throw new DatabaseTypeUnsupportedException(databaseType.name());
+ }
+ return registry.get(databaseType);
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResult.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResult.java
new file mode 100644
index 0000000000000..d6a768aafc3e8
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/SQLParsedResult.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.parser.result;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext;
+import com.dangdang.ddframe.rdb.sharding.parser.result.router.ConditionContext;
+import com.dangdang.ddframe.rdb.sharding.parser.result.router.RouteContext;
+
+import lombok.Getter;
+import lombok.ToString;
+
+/**
+ * SQL解析结果.
+ *
+ * @author gaohongtao, zhangliang
+ */
+@Getter
+@ToString
+public final class SQLParsedResult {
+
+ private final RouteContext routeContext = new RouteContext();
+
+ private final List conditionContexts = new ArrayList<>();
+
+ private final MergeContext mergeContext = new MergeContext();
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/AggregationColumn.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/AggregationColumn.java
new file mode 100644
index 0000000000000..5a44751dac419
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/AggregationColumn.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.parser.result.merger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.common.base.Optional;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * 聚合列对象.
+ *
+ * @author zhangliang
+ */
+@Getter
+@AllArgsConstructor
+@RequiredArgsConstructor
+@ToString
+public final class AggregationColumn {
+
+ private final String expression;
+
+ private final AggregationType aggregationType;
+
+ private final Optional alias;
+
+ private final Optional option;
+
+ private final List derivedColumns = new ArrayList<>(2);
+
+ @Setter
+ private int index = -1;
+
+ /**
+ * 聚合函数类型.
+ *
+ * @author gaohongtao
+ */
+ public enum AggregationType {
+ MAX, MIN, SUM, COUNT, AVG
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/GroupByColumn.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/GroupByColumn.java
new file mode 100644
index 0000000000000..9a540c68a9de5
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/GroupByColumn.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.parser.result.merger;
+
+import com.dangdang.ddframe.rdb.sharding.parser.result.merger.OrderByColumn.OrderByType;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 分组列对象.
+ *
+ * @author zhangliang
+ */
+@RequiredArgsConstructor
+@Getter
+@ToString
+public final class GroupByColumn {
+
+ private final String name;
+
+ private final String alias;
+
+ private final OrderByType orderByType;
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/Limit.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/Limit.java
new file mode 100644
index 0000000000000..bd12de46e78d9
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/Limit.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.parser.result.merger;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 分页对象.
+ *
+ * @author gaohongtao
+ */
+@RequiredArgsConstructor
+@Getter
+@ToString
+public class Limit {
+
+ private final int offset;
+
+ private final int rowCount;
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/MergeContext.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/MergeContext.java
new file mode 100644
index 0000000000000..470473aa02889
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/MergeContext.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.parser.result.merger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * 结果归并上下文.
+ *
+ * @author zhangliang
+ */
+@Getter
+@ToString
+public final class MergeContext {
+
+ private final List orderByColumns = new ArrayList<>();
+
+ private final List groupByColumns = new ArrayList<>();
+
+ private final List aggregationColumns = new ArrayList<>();
+
+ @Setter
+ private Limit limit;
+
+ /**
+ * 获取结果集类型.
+ *
+ * @return 结果集类型
+ */
+ public ResultSetType getResultSetType() {
+ if (!groupByColumns.isEmpty()) {
+ return ResultSetType.GroupBy;
+ }
+ if (!aggregationColumns.isEmpty()) {
+ return ResultSetType.Aggregate;
+ }
+ if (!orderByColumns.isEmpty()) {
+ return ResultSetType.OrderBy;
+ }
+ return ResultSetType.Iterator;
+ }
+
+ /**
+ * 结果集类型.
+ *
+ * @author zhangliang
+ */
+ public enum ResultSetType {
+ Iterator, OrderBy, Aggregate, GroupBy
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/OrderByColumn.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/OrderByColumn.java
new file mode 100644
index 0000000000000..bef8af3495b20
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/merger/OrderByColumn.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.parser.result.merger;
+
+import com.alibaba.druid.sql.ast.SQLOrderingSpecification;
+import com.google.common.base.Optional;
+
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 排序列对象.
+ *
+ * @author zhangliang
+ */
+@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+@Getter
+@ToString
+public final class OrderByColumn {
+
+ private final Optional name;
+
+ private final Optional index;
+
+ private final OrderByType orderByType;
+
+ public OrderByColumn(final String name, final OrderByType orderByType) {
+ this(Optional.of(name), Optional.absent(), orderByType);
+ }
+
+ public OrderByColumn(final int index, final OrderByType orderByType) {
+ this(Optional.absent(), Optional.of(index), orderByType);
+ }
+
+ /**
+ * 排序类型.
+ *
+ * @author gaohongtao, zhangliang
+ */
+ public enum OrderByType {
+ ASC,
+ DESC;
+
+ /**
+ * 适配Druid的枚举类型.
+ *
+ * @param sqlOrderingSpecification Druid的枚举类型
+ * @return 排序类型
+ */
+ public static OrderByType valueOf(final SQLOrderingSpecification sqlOrderingSpecification) {
+ return OrderByType.valueOf(sqlOrderingSpecification.name());
+ }
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/Condition.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/Condition.java
new file mode 100644
index 0000000000000..48cbd3da2472e
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/Condition.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.dangdang.ddframe.rdb.sharding.parser.result.router;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 条件对象.
+ *
+ * @author gaohongtao
+ */
+@RequiredArgsConstructor
+@Getter
+@ToString
+@EqualsAndHashCode
+public final class Condition {
+
+ private final Column column;
+
+ private final BinaryOperator operator;
+
+ private final List> values = new ArrayList<>();
+
+ /**
+ * 列对象.
+ *
+ * @author gaohongtao, zhangliang
+ */
+ @RequiredArgsConstructor
+ @Getter
+ @EqualsAndHashCode
+ @ToString
+ public static final class Column {
+
+ private final String columnName;
+
+ private final String tableName;
+ }
+
+ /**
+ * 操作符枚举.
+ *
+ * @author gaohongtao, zhangliang
+ */
+ @RequiredArgsConstructor
+ public enum BinaryOperator {
+
+ EQUAL("="), BETWEEN("BETWEEN"), IN("IN"), NOT_IN("NOT IN");
+
+ @Getter
+ private final String expression;
+
+ @Override
+ public String toString() {
+ return expression;
+ }
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/ConditionContext.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/ConditionContext.java
new file mode 100644
index 0000000000000..e2b59b72305a6
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parser/result/router/ConditionContext.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright 1999-2015 dangdang.com.
+ *