From 1303d55c36c20f3450ecc47c5a8c5868cf08129a Mon Sep 17 00:00:00 2001
From: terrymanu
Date: Mon, 30 May 2016 17:26:40 +0800
Subject: [PATCH] for #85 use datasource to manage master slave
---
README.md | 16 ++--
.../META-INF/rdb/withoutNamespace.xml | 25 ++---
.../rdb/withoutNamespaceStrategyOutside.xml | 17 +---
.../api/MasterSlaveDataSourceFactory.java | 47 ++++++++++
.../api/ShardingDataSourceFactory.java | 2 +
.../rdb/sharding/api/rule/ShardingRule.java | 41 +--------
.../rdb/sharding/api/rule/TableRule.java | 92 ++++++-------------
.../RoundRobinSlaveLoadBalanceStrategy.java | 7 +-
.../slave/SlaveLoadBalanceStrategy.java | 3 +-
.../MasterSlaveDataSource.java} | 37 ++++----
.../rdb/sharding/jdbc/ShardingConnection.java | 19 ++--
.../rdb/sharding/jdbc/ShardingDataSource.java | 14 +--
.../adapter/AbstractDataSourceAdapter.java | 6 ++
...AbstractShardingMasterSlaveDBUnitTest.java | 49 ++++++----
...ngMasterSlaveForPStatementWithDMLTest.java | 2 +-
...asterSlaveForPStatementWithSelectTest.java | 3 +-
...ingMasterSlaveForStatementWithDMLTest.java | 2 +-
.../AbstractShardingNullableDBUnitTest.java | 4 +-
.../ddframe/rdb/sharding/api/AllApiTests.java | 3 +-
.../api/MasterSlaveDataSourceFactoryTest.java | 39 ++++++++
.../sharding/api/rule/DataSourceRuleTest.java | 2 +-
.../api/rule/MasterSlaveRuleTest.java | 76 ---------------
.../sharding/api/rule/ShardingRuleTest.java | 14 ---
...oundRobinSlaveLoadBalanceStrategyTest.java | 10 +-
.../rule => }/fixture/TestDataSource.java | 7 +-
.../rdb/sharding/jdbc/AllJDBCTests.java | 3 +-
.../jdbc/MasterSlaveDataSourceTest.java | 64 +++++++++++++
.../sharding/jdbc/ShardingDataSourceTest.java | 8 --
.../jdbc/adapter/DataSourceAdapterTest.java | 7 ++
.../merger/fixture/MockResultSet.java | 2 +-
sharding-jdbc-doc/content/index/index.md | 69 ++++++++++++--
.../content/post/master_slave.md | 24 ++---
32 files changed, 374 insertions(+), 340 deletions(-)
create mode 100644 sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/MasterSlaveDataSourceFactory.java
rename sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/{api/rule/MasterSlaveRule.java => jdbc/MasterSlaveDataSource.java} (67%)
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/MasterSlaveDataSourceFactoryTest.java
delete mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/MasterSlaveRuleTest.java
rename sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/{api/rule => }/fixture/TestDataSource.java (83%)
create mode 100644 sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSourceTest.java
diff --git a/README.md b/README.md
index 9b39a8cd6d04c..2f3d0b3a7661a 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,8 @@
* 分片策略灵活,可支持`=`,`BETWEEN`,`IN`等多维度分片,也可支持多分片键共用。
* `SQL`解析功能完善,支持聚合,分组,排序,`Limit`,`OR`等查询,并且支持`Binding Table`以及笛卡尔积的表查询。
+* 支持柔性事务(目前仅最大努力送达型)。
+* 支持读写分离。
`Sharding-JDBC`配置多样:
@@ -123,14 +125,16 @@
## 规则配置
`Sharding-JDBC`的分库分表通过规则配置描述,请简单浏览配置全貌:
+
```java
- ShardingRule shardingRule = ShardingRule.builder()
+ShardingRule shardingRule = ShardingRule.builder()
.dataSourceRule(dataSourceRule)
- .tableRules(tableRules)
- .databaseShardingStrategy(new DatabaseShardingStrategy("sharding_column_1", new XXXShardingAlgorithm()))
- .tableShardingStrategy(new TableShardingStrategy("sharding_column_2", new XXXShardingAlgorithm())))
+ .tableRules(tableRuleList)
+ .databaseShardingStrategy(new DatabaseShardingStrategy("sharding_column", new XXXShardingAlgorithm()))
+ .tableShardingStrategy(new TableShardingStrategy("sharding_column", new XXXShardingAlgorithm())))
.build();
```
+
规则配置包括数据源配置、表规则配置、分库策略和分表策略组成。这只是最简单的配置方式,实际使用可更加灵活,如:多分片键,分片策略直接和`tableRule`绑定等。
>详细的规则配置请参考[用户指南](http://dangdangdotcom.github.io/sharding-jdbc/post/user_guide/)
@@ -138,6 +142,7 @@
## 使用原生JDBC接口
通过`ShardingDataSourceFactory`工厂和规则配置对象获取`ShardingDataSource`,`ShardingDataSource`实现自`JDBC`的标准接口`DataSource`。然后可通过`DataSource`选择使用原生`JDBC`开发,或者使用`JPA`, `MyBatis`等`ORM`工具。
以`JDBC`原生实现为例:
+
```java
DataSource dataSource = ShardingDataSourceFactory.createDataSource(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=?";
@@ -150,15 +155,14 @@ try (
while(rs.next()) {
System.out.println(rs.getInt(1));
System.out.println(rs.getInt(2));
- System.out.println(rs.getInt(3));
}
}
}
```
## 使用Spring命名空间配置
-```xml
+```xml
t_order_3
-
-
-
-
-
+
+
-
-
+
+
@@ -50,15 +47,12 @@
t_order_item_3
-
-
-
-
-
+
+
-
-
+
+
@@ -92,9 +86,6 @@
-
-
-
diff --git a/sharding-jdbc-config-parent/sharding-jdbc-config-spring/src/test/resources/META-INF/rdb/withoutNamespaceStrategyOutside.xml b/sharding-jdbc-config-parent/sharding-jdbc-config-spring/src/test/resources/META-INF/rdb/withoutNamespaceStrategyOutside.xml
index 26b45f8665d68..a14309468e920 100644
--- a/sharding-jdbc-config-parent/sharding-jdbc-config-spring/src/test/resources/META-INF/rdb/withoutNamespaceStrategyOutside.xml
+++ b/sharding-jdbc-config-parent/sharding-jdbc-config-spring/src/test/resources/META-INF/rdb/withoutNamespaceStrategyOutside.xml
@@ -27,19 +27,16 @@
t_order_3
-
+
+
-
-
-
-
@@ -53,19 +50,16 @@
t_order_item_3
-
+
+
-
-
-
-
@@ -95,9 +89,6 @@
-
-
-
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/MasterSlaveDataSourceFactory.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/MasterSlaveDataSourceFactory.java
new file mode 100644
index 0000000000000..f926afffdd101
--- /dev/null
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/MasterSlaveDataSourceFactory.java
@@ -0,0 +1,47 @@
+/*
+ * 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.jdbc.MasterSlaveDataSource;
+import com.google.common.collect.Lists;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import javax.sql.DataSource;
+
+/**
+ * 读写分离数据源工厂.
+ *
+ * @author zhangliang
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class MasterSlaveDataSourceFactory {
+
+ /**
+ * 创建读写分离数据源.
+ *
+ * @param logicDataSourceName 逻辑数据源名称
+ * @param masterDataSource 主节点数据源
+ * @param slaveDataSource 从节点数据源
+ * @param otherSlaveDataSources 其他从节点数据源
+ * @return 读写分离数据源
+ */
+ public static DataSource createDataSource(final String logicDataSourceName, final DataSource masterDataSource, final DataSource slaveDataSource, final DataSource... otherSlaveDataSources) {
+ return new MasterSlaveDataSource(logicDataSourceName, masterDataSource, Lists.asList(slaveDataSource, otherSlaveDataSources));
+ }
+}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/ShardingDataSourceFactory.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/ShardingDataSourceFactory.java
index 27d3ab4720c65..066ebbac4887f 100644
--- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/ShardingDataSourceFactory.java
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/ShardingDataSourceFactory.java
@@ -27,6 +27,8 @@
/**
* 分片数据源工厂.
+ *
+ * @author zhangliang
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ShardingDataSourceFactory {
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
index cd783c3ea701a..4289609373933 100644
--- 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
@@ -21,11 +21,8 @@
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.Function;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@@ -33,7 +30,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
-import java.util.Map;
import java.util.Set;
/**
@@ -54,9 +50,6 @@ public final class ShardingRule {
private final TableShardingStrategy tableShardingStrategy;
- @Getter(AccessLevel.NONE)
- private final Map masterSlaveRuleMap;
-
/**
* 全属性构造器.
*
@@ -69,7 +62,7 @@ public final class ShardingRule {
@Deprecated
public ShardingRule(
final DataSourceRule dataSourceRule, final Collection tableRules, final Collection bindingTableRules,
- final DatabaseShardingStrategy databaseShardingStrategy, final TableShardingStrategy tableShardingStrategy, final Collection masterSlaveRules) {
+ final DatabaseShardingStrategy databaseShardingStrategy, final TableShardingStrategy tableShardingStrategy) {
Preconditions.checkNotNull(dataSourceRule);
Preconditions.checkNotNull(tableRules);
this.dataSourceRule = dataSourceRule;
@@ -79,13 +72,6 @@ public ShardingRule(
Collections.emptyList(), new NoneDatabaseShardingAlgorithm()) : databaseShardingStrategy;
this.tableShardingStrategy = null == tableShardingStrategy ? new TableShardingStrategy(
Collections.emptyList(), new NoneTableShardingAlgorithm()) : tableShardingStrategy;
- masterSlaveRuleMap = Maps.uniqueIndex(null == masterSlaveRules ? Collections.emptyList() : masterSlaveRules, new Function() {
-
- @Override
- public String apply(final MasterSlaveRule input) {
- return input.getLogicDataSource();
- }
- });
}
/**
@@ -226,16 +212,6 @@ public Collection getAllShardingColumns() {
return result;
}
- /**
- * 根据逻辑数据源名称获取读写分离配置.
- *
- * @param logicDataSource 逻辑数据源名称
- * @return 读写分离配置
- */
- public Optional findMasterSlaveRule(final String logicDataSource) {
- return Optional.fromNullable(masterSlaveRuleMap.get(logicDataSource));
- }
-
/**
* 分片规则配置对象构建器.
*/
@@ -252,8 +228,6 @@ public static class ShardingRuleBuilder {
private TableShardingStrategy tableShardingStrategy;
- private Collection masterSlaveRules;
-
/**
* 构建数据源配置规则.
*
@@ -309,24 +283,13 @@ public ShardingRuleBuilder tableShardingStrategy(final TableShardingStrategy tab
return this;
}
- /**
- * 构建数据源分片规则.
- *
- * @param masterSlaveRules 读写分离策略集合
- * @return 分片规则配置对象构建器
- */
- public ShardingRuleBuilder masterSlaveRules(final Collection masterSlaveRules) {
- this.masterSlaveRules = masterSlaveRules;
- return this;
- }
-
/**
* 构建分片规则配置对象.
*
* @return 分片规则配置对象
*/
public ShardingRule build() {
- return new ShardingRule(dataSourceRule, tableRules, bindingTableRules, databaseShardingStrategy, tableShardingStrategy, masterSlaveRules);
+ return new ShardingRule(dataSourceRule, tableRules, bindingTableRules, databaseShardingStrategy, tableShardingStrategy);
}
}
}
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
index 99da1a7505431..e7d9de460adac 100644
--- 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
@@ -19,9 +19,7 @@
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.Function;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
@@ -61,8 +59,8 @@ public final class TableRule {
* @deprecated 未来将改为private权限, 不在对外公开, 不建议使用非Spring命名空间的配置.
*/
@Deprecated
- public TableRule(final String logicTable, final boolean dynamic, final List actualTables, final Collection masterSlaveRules, final DataSourceRule dataSourceRule,
- final Collection dataSourceNames, final DatabaseShardingStrategy databaseShardingStrategy, final TableShardingStrategy tableShardingStrategy) {
+ public TableRule(final String logicTable, final boolean dynamic, final List actualTables, final DataSourceRule dataSourceRule, final Collection dataSourceNames,
+ final DatabaseShardingStrategy databaseShardingStrategy, final TableShardingStrategy tableShardingStrategy) {
Preconditions.checkNotNull(logicTable);
this.logicTable = logicTable;
this.dynamic = dynamic;
@@ -70,27 +68,27 @@ public TableRule(final String logicTable, final boolean dynamic, final List generateDataNodes(final Collection masterSlaveRules, final DataSourceRule dataSourceRule) {
- Collection dataSourceNames = getLogicDataSourceNames(masterSlaveRules, dataSourceRule.getDataSourceNames());
+ private List generateDataNodes(final DataSourceRule dataSourceRule) {
+ Collection dataSourceNames = dataSourceRule.getDataSourceNames();
List result = new ArrayList<>(dataSourceNames.size());
for (String each : dataSourceNames) {
result.add(new DynamicDataNode(each));
@@ -98,9 +96,8 @@ private List generateDataNodes(final Collection maste
return result;
}
- private List generateDataNodes(final List actualTables, final Collection masterSlaveRules,
- final DataSourceRule dataSourceRule, final Collection actualDataSourceNames) {
- Collection dataSourceNames = getLogicDataSourceNames(masterSlaveRules, getDataSourceNames(masterSlaveRules, dataSourceRule, actualDataSourceNames));
+ private List generateDataNodes(final List actualTables, final DataSourceRule dataSourceRule, final Collection actualDataSourceNames) {
+ Collection dataSourceNames = getDataSourceNames(dataSourceRule, actualDataSourceNames);
List result = new ArrayList<>(actualTables.size() * (dataSourceNames.isEmpty() ? 1 : dataSourceNames.size()));
for (String actualTable : actualTables) {
if (DataNode.isValidDataNode(actualTable)) {
@@ -114,41 +111,19 @@ private List generateDataNodes(final List actualTables, final
return result;
}
- private Collection getDataSourceNames(final Collection masterSlaveRules, final DataSourceRule dataSourceRule, final Collection actualDataSourceNames) {
+ private Collection getDataSourceNames(final DataSourceRule dataSourceRule, final Collection actualDataSourceNames) {
if (null == dataSourceRule) {
return Collections.emptyList();
}
if (null == actualDataSourceNames || actualDataSourceNames.isEmpty()) {
return dataSourceRule.getDataSourceNames();
}
- return getLogicDataSourceNames(masterSlaveRules, actualDataSourceNames);
- }
-
- private Collection getLogicDataSourceNames(final Collection masterSlaveRules, final Collection dataSourceNames) {
- if (null == masterSlaveRules) {
- return dataSourceNames;
- }
- return Collections2.transform(dataSourceNames, new Function() {
-
- @Override
- public String apply(final String input) {
- return getLogicDataSourceName(masterSlaveRules, input);
- }
- });
- }
-
- private String getLogicDataSourceName(final Collection masterSlaveRules, final String dataSourceName) {
- for (MasterSlaveRule each : masterSlaveRules) {
- if (each.within(dataSourceName)) {
- return each.getLogicDataSource();
- }
- }
- return dataSourceName;
+ return actualDataSourceNames;
}
/**
* 根据数据源名称过滤获取真实数据单元.
- *
+ *
* @param targetDataSources 数据源名称集合
* @param targetTables 真实表名称集合
* @return 真实数据单元
@@ -193,7 +168,7 @@ public Collection getActualDatasourceNames() {
/**
* 根据数据源名称过滤获取真实表名称.
- *
+ *
* @param targetDataSources 数据源名称
* @return 真实表名称
*/
@@ -229,11 +204,9 @@ public static class TableRuleBuilder {
private boolean dynamic;
private List actualTables;
-
- private Collection masterSlaveRules;
-
+
private DataSourceRule dataSourceRule;
-
+
private Collection dataSourceNames;
private DatabaseShardingStrategy databaseShardingStrategy;
@@ -242,9 +215,9 @@ public static class TableRuleBuilder {
/**
* 构建是否为动态表.
- *
+ *
* @param dynamic 是否为动态表
- * @return 规则配置对象构建器
+ * @return 真实表集合
*/
public TableRuleBuilder dynamic(final boolean dynamic) {
this.dynamic = dynamic;
@@ -253,29 +226,18 @@ public TableRuleBuilder dynamic(final boolean dynamic) {
/**
* 构建真实表集合.
- *
+ *
* @param actualTables 真实表集合
- * @return 规则配置对象构建器
+ * @return 真实表集合
*/
public TableRuleBuilder actualTables(final List actualTables) {
this.actualTables = actualTables;
return this;
}
-
- /**
- * 构建读写分离规则.
- *
- * @param masterSlaveRules 读写分离规则
- * @return 规则配置对象构建器
- */
- public TableRuleBuilder masterSlaveRules(final Collection masterSlaveRules) {
- this.masterSlaveRules = masterSlaveRules;
- return this;
- }
/**
* 构建数据源分片规则.
- *
+ *
* @param dataSourceRule 数据源分片规则
* @return 规则配置对象构建器
*/
@@ -283,7 +245,7 @@ public TableRuleBuilder dataSourceRule(final DataSourceRule dataSourceRule) {
this.dataSourceRule = dataSourceRule;
return this;
}
-
+
/**
* 构建数据源分片规则.
*
@@ -297,7 +259,7 @@ public TableRuleBuilder dataSourceNames(final Collection dataSourceNames
/**
* 构建数据库分片策略.
- *
+ *
* @param databaseShardingStrategy 数据库分片策略
* @return 规则配置对象构建器
*/
@@ -308,7 +270,7 @@ public TableRuleBuilder databaseShardingStrategy(final DatabaseShardingStrategy
/**
* 构建表分片策略.
- *
+ *
* @param tableShardingStrategy 表分片策略
* @return 规则配置对象构建器
*/
@@ -319,11 +281,11 @@ public TableRuleBuilder tableShardingStrategy(final TableShardingStrategy tableS
/**
* 构建表规则配置对象.
- *
+ *
* @return 表规则配置对象
*/
public TableRule build() {
- return new TableRule(logicTable, dynamic, actualTables, masterSlaveRules, dataSourceRule, dataSourceNames, databaseShardingStrategy, tableShardingStrategy);
+ return new TableRule(logicTable, dynamic, actualTables, dataSourceRule, dataSourceNames, databaseShardingStrategy, tableShardingStrategy);
}
}
}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/slave/RoundRobinSlaveLoadBalanceStrategy.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/slave/RoundRobinSlaveLoadBalanceStrategy.java
index 283940761fd42..a601cd8a0e2b7 100644
--- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/slave/RoundRobinSlaveLoadBalanceStrategy.java
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/slave/RoundRobinSlaveLoadBalanceStrategy.java
@@ -17,6 +17,7 @@
package com.dangdang.ddframe.rdb.sharding.api.strategy.slave;
+import javax.sql.DataSource;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@@ -31,12 +32,10 @@ public final class RoundRobinSlaveLoadBalanceStrategy implements SlaveLoadBalanc
private static final ConcurrentHashMap COUNT_MAP = new ConcurrentHashMap<>();
@Override
- public String getDataSource(final String logicDataSource, final List slaveDataSources) {
+ public DataSource getDataSource(final String logicDataSource, final List slaveDataSources) {
AtomicInteger count = COUNT_MAP.containsKey(logicDataSource) ? COUNT_MAP.get(logicDataSource) : new AtomicInteger(0);
COUNT_MAP.putIfAbsent(logicDataSource, count);
- if (count.get() >= slaveDataSources.size()) {
- count.set(0);
- }
+ count.compareAndSet(slaveDataSources.size(), 0);
return slaveDataSources.get(count.getAndIncrement() % slaveDataSources.size());
}
}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/slave/SlaveLoadBalanceStrategy.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/slave/SlaveLoadBalanceStrategy.java
index 7bd4fe4b8bb75..88a1076164b27 100644
--- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/slave/SlaveLoadBalanceStrategy.java
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/strategy/slave/SlaveLoadBalanceStrategy.java
@@ -17,6 +17,7 @@
package com.dangdang.ddframe.rdb.sharding.api.strategy.slave;
+import javax.sql.DataSource;
import java.util.List;
/**
@@ -33,5 +34,5 @@ public interface SlaveLoadBalanceStrategy {
* @param slaveDataSources 从库数据源列表
* @return 选中的从库数据源
*/
- String getDataSource(final String logicDataSource, final List slaveDataSources);
+ DataSource getDataSource(final String logicDataSource, final List slaveDataSources);
}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/MasterSlaveRule.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSource.java
similarity index 67%
rename from sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/MasterSlaveRule.java
rename to sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSource.java
index 35fc3ba7a5064..409df3af7a490 100644
--- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/rule/MasterSlaveRule.java
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSource.java
@@ -15,24 +15,26 @@
*
*/
-package com.dangdang.ddframe.rdb.sharding.api.rule;
+package com.dangdang.ddframe.rdb.sharding.jdbc;
import com.dangdang.ddframe.rdb.sharding.api.strategy.slave.RoundRobinSlaveLoadBalanceStrategy;
import com.dangdang.ddframe.rdb.sharding.api.strategy.slave.SlaveLoadBalanceStrategy;
+import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractDataSourceAdapter;
import com.dangdang.ddframe.rdb.sharding.parser.result.router.SQLStatementType;
-import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
import java.util.List;
/**
- * 读写分离配置规则.
+ * 支持读写分离的数据源.
*
* @author zhangliang
*/
@RequiredArgsConstructor
-@Getter
-public final class MasterSlaveRule {
+public final class MasterSlaveDataSource extends AbstractDataSourceAdapter {
private static final ThreadLocal WAS_UPDATED = new ThreadLocal() {
@@ -42,35 +44,30 @@ protected Boolean initialValue() {
}
};
- private final String logicDataSource;
+ private final String logicDataSourceName;
- private final String masterDataSource;
+ private final DataSource masterDataSource;
- private final List slaveDataSources;
+ private final List slaveDataSources;
private final SlaveLoadBalanceStrategy slaveLoadBalanceStrategy = new RoundRobinSlaveLoadBalanceStrategy();
/**
* 获取主或从节点的数据源名称.
- *
+ *
* @param sqlStatementType SQL类型
- * @return 主或从节点的数据源名称
+ * @return 主或从节点的数据源
*/
- public String getMasterOrSlaveDataSource(final SQLStatementType sqlStatementType) {
+ public DataSource getDataSource(final SQLStatementType sqlStatementType) {
if (SQLStatementType.SELECT != sqlStatementType || WAS_UPDATED.get()) {
WAS_UPDATED.set(true);
return masterDataSource;
}
- return slaveLoadBalanceStrategy.getDataSource(logicDataSource, slaveDataSources);
+ return slaveLoadBalanceStrategy.getDataSource(logicDataSourceName, slaveDataSources);
}
- /**
- * 判断该真实数据源是否属于本读写分离规则配置.
- *
- * @param actualDataSource 真实数据源名称
- * @return 是否属于本读写分离规则配置
- */
- public boolean within(final String actualDataSource) {
- return actualDataSource.equals(masterDataSource) || slaveDataSources.contains(actualDataSource);
+ @Override
+ public Connection getConnection() throws SQLException {
+ throw new UnsupportedOperationException("Master slave data source cannot support get connection directly.");
}
}
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
index 4da06ca3af496..17bbe32236b5d 100644
--- 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
@@ -18,16 +18,15 @@
package com.dangdang.ddframe.rdb.sharding.jdbc;
import com.codahale.metrics.Timer.Context;
-import com.dangdang.ddframe.rdb.sharding.api.rule.MasterSlaveRule;
import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractConnectionAdapter;
import com.dangdang.ddframe.rdb.sharding.metrics.MetricsContext;
import com.dangdang.ddframe.rdb.sharding.parser.result.router.SQLStatementType;
import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
@@ -70,15 +69,17 @@ public DatabaseMetaData getMetaData() throws SQLException {
}
private Connection getConnectionInternal(final String dataSourceName, final SQLStatementType sqlStatementType) throws SQLException {
- Optional masterSlaveRule = shardingContext.getShardingRule().findMasterSlaveRule(dataSourceName);
- String actualDataSourceName = masterSlaveRule.isPresent() ? masterSlaveRule.get().getMasterOrSlaveDataSource(sqlStatementType) : dataSourceName;
- if (connectionMap.containsKey(actualDataSourceName)) {
- return connectionMap.get(actualDataSourceName);
+ if (connectionMap.containsKey(dataSourceName)) {
+ return connectionMap.get(dataSourceName);
}
- Context metricsContext = MetricsContext.start(Joiner.on("-").join("ShardingConnection-getConnection", actualDataSourceName));
- Connection result = shardingContext.getShardingRule().getDataSourceRule().getDataSource(actualDataSourceName).getConnection();
+ Context metricsContext = MetricsContext.start(Joiner.on("-").join("ShardingConnection-getConnection", dataSourceName));
+ DataSource dataSource = shardingContext.getShardingRule().getDataSourceRule().getDataSource(dataSourceName);
+ if (dataSource instanceof MasterSlaveDataSource) {
+ dataSource = ((MasterSlaveDataSource) dataSource).getDataSource(sqlStatementType);
+ }
+ Connection result = dataSource.getConnection();
MetricsContext.stop(metricsContext);
- connectionMap.put(actualDataSourceName, result);
+ connectionMap.put(dataSourceName, result);
return result;
}
diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingDataSource.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingDataSource.java
index e004f2c46942a..9c7b262f7c3a0 100644
--- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingDataSource.java
+++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingDataSource.java
@@ -24,6 +24,7 @@
import com.dangdang.ddframe.rdb.sharding.executor.ExecutorEngine;
import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractDataSourceAdapter;
import com.dangdang.ddframe.rdb.sharding.metrics.MetricsContext;
+import com.dangdang.ddframe.rdb.sharding.parser.result.router.SQLStatementType;
import com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine;
import com.google.common.base.Preconditions;
@@ -64,7 +65,13 @@ private String getDatabaseProductName(final ShardingRule shardingRule) throws SQ
String result = null;
Collection connections = new ArrayList<>(shardingRule.getDataSourceRule().getDataSources().size());
for (DataSource each : shardingRule.getDataSourceRule().getDataSources()) {
- Connection connection = each.getConnection();
+ DataSource dataSource;
+ if (each instanceof MasterSlaveDataSource) {
+ dataSource = ((MasterSlaveDataSource) each).getDataSource(SQLStatementType.SELECT);
+ } else {
+ dataSource = each;
+ }
+ Connection connection = dataSource.getConnection();
connections.add(connection);
String databaseProductName = connection.getMetaData().getDatabaseProductName();
Preconditions.checkState(null == result || result.equals(databaseProductName), String.format("Database type inconsistent with '%s' and '%s'", result, databaseProductName));
@@ -81,9 +88,4 @@ public ShardingConnection getConnection() throws SQLException {
MetricsContext.init(shardingProperties);
return new ShardingConnection(shardingContext);
}
-
- @Override
- public final ShardingConnection 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/jdbc/adapter/AbstractDataSourceAdapter.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/AbstractDataSourceAdapter.java
index b32e76a515d25..540a25e0c20a8 100644
--- 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
@@ -21,6 +21,7 @@
import lombok.RequiredArgsConstructor;
import java.io.PrintWriter;
+import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
@@ -49,4 +50,9 @@ public final void setLogWriter(final PrintWriter out) throws SQLException {
public final Logger getParentLogger() throws SQLFeatureNotSupportedException {
return Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
}
+
+ @Override
+ public final Connection getConnection(final String username, final String password) throws SQLException {
+ return getConnection();
+ }
}
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/AbstractShardingMasterSlaveDBUnitTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/AbstractShardingMasterSlaveDBUnitTest.java
index 2da4a8e028463..70523b19fbce7 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/AbstractShardingMasterSlaveDBUnitTest.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/AbstractShardingMasterSlaveDBUnitTest.java
@@ -22,11 +22,11 @@
import com.dangdang.ddframe.rdb.integrate.fixture.SingleKeyModuloTableShardingAlgorithm;
import com.dangdang.ddframe.rdb.sharding.api.rule.BindingTableRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule;
-import com.dangdang.ddframe.rdb.sharding.api.rule.MasterSlaveRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy;
+import com.dangdang.ddframe.rdb.sharding.jdbc.MasterSlaveDataSource;
import com.dangdang.ddframe.rdb.sharding.jdbc.ShardingDataSource;
import org.junit.After;
import org.junit.Before;
@@ -34,8 +34,8 @@
import javax.sql.DataSource;
import java.lang.reflect.Field;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -46,9 +46,9 @@ public abstract class AbstractShardingMasterSlaveDBUnitTest extends AbstractDBUn
@Before
@After
public void reset() throws NoSuchFieldException, IllegalAccessException {
- Field field = MasterSlaveRule.class.getDeclaredField("WAS_UPDATED");
+ Field field = MasterSlaveDataSource.class.getDeclaredField("WAS_UPDATED");
field.setAccessible(true);
- ((ThreadLocal) field.get(MasterSlaveRule.class)).remove();
+ ((ThreadLocal) field.get(MasterSlaveDataSource.class)).remove();
}
@Override
@@ -102,19 +102,29 @@ protected List getDataSetFiles() {
}
protected final ShardingDataSource getShardingDataSource() {
- Map dataSourceMap = createDataSourceMap(dataSourceName);
+ Map masterSlaveDataSourceMap = createDataSourceMap(dataSourceName);
+ MasterSlaveDataSource masterSlaveDs0 = new MasterSlaveDataSource("ms_0", masterSlaveDataSourceMap.get("dataSource_master_0"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_0")));
+ MasterSlaveDataSource masterSlaveDs1 = new MasterSlaveDataSource("ms_1", masterSlaveDataSourceMap.get("dataSource_master_1"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_1")));
+ MasterSlaveDataSource masterSlaveDs2 = new MasterSlaveDataSource("ms_2", masterSlaveDataSourceMap.get("dataSource_master_2"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_2")));
+ MasterSlaveDataSource masterSlaveDs3 = new MasterSlaveDataSource("ms_3", masterSlaveDataSourceMap.get("dataSource_master_3"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_3")));
+ MasterSlaveDataSource masterSlaveDs4 = new MasterSlaveDataSource("ms_4", masterSlaveDataSourceMap.get("dataSource_master_4"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_4")));
+ MasterSlaveDataSource masterSlaveDs5 = new MasterSlaveDataSource("ms_5", masterSlaveDataSourceMap.get("dataSource_master_5"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_5")));
+ MasterSlaveDataSource masterSlaveDs6 = new MasterSlaveDataSource("ms_6", masterSlaveDataSourceMap.get("dataSource_master_6"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_6")));
+ MasterSlaveDataSource masterSlaveDs7 = new MasterSlaveDataSource("ms_7", masterSlaveDataSourceMap.get("dataSource_master_7"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_7")));
+ MasterSlaveDataSource masterSlaveDs8 = new MasterSlaveDataSource("ms_8", masterSlaveDataSourceMap.get("dataSource_master_8"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_8")));
+ MasterSlaveDataSource masterSlaveDs9 = new MasterSlaveDataSource("ms_9", masterSlaveDataSourceMap.get("dataSource_master_9"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_9")));
+ Map dataSourceMap = new HashMap<>(10);
+ dataSourceMap.put("ms_0", masterSlaveDs0);
+ dataSourceMap.put("ms_1", masterSlaveDs1);
+ dataSourceMap.put("ms_2", masterSlaveDs2);
+ dataSourceMap.put("ms_3", masterSlaveDs3);
+ dataSourceMap.put("ms_4", masterSlaveDs4);
+ dataSourceMap.put("ms_5", masterSlaveDs5);
+ dataSourceMap.put("ms_6", masterSlaveDs6);
+ dataSourceMap.put("ms_7", masterSlaveDs7);
+ dataSourceMap.put("ms_8", masterSlaveDs8);
+ dataSourceMap.put("ms_9", masterSlaveDs9);
DataSourceRule dataSourceRule = new DataSourceRule(dataSourceMap);
- Collection masterSlaveRules = Arrays.asList(
- new MasterSlaveRule("ms_0", "dataSource_master_0", Collections.singletonList("dataSource_slave_0")),
- new MasterSlaveRule("ms_1", "dataSource_master_1", Collections.singletonList("dataSource_slave_1")),
- new MasterSlaveRule("ms_2", "dataSource_master_2", Collections.singletonList("dataSource_slave_2")),
- new MasterSlaveRule("ms_3", "dataSource_master_3", Collections.singletonList("dataSource_slave_3")),
- new MasterSlaveRule("ms_4", "dataSource_master_4", Collections.singletonList("dataSource_slave_4")),
- new MasterSlaveRule("ms_5", "dataSource_master_5", Collections.singletonList("dataSource_slave_5")),
- new MasterSlaveRule("ms_6", "dataSource_master_6", Collections.singletonList("dataSource_slave_6")),
- new MasterSlaveRule("ms_7", "dataSource_master_7", Collections.singletonList("dataSource_slave_7")),
- new MasterSlaveRule("ms_8", "dataSource_master_8", Collections.singletonList("dataSource_slave_8")),
- new MasterSlaveRule("ms_9", "dataSource_master_9", Collections.singletonList("dataSource_slave_9")));
TableRule orderTableRule = TableRule.builder("t_order").actualTables(Arrays.asList(
"t_order_0",
"t_order_1",
@@ -125,7 +135,7 @@ protected final ShardingDataSource getShardingDataSource() {
"t_order_6",
"t_order_7",
"t_order_8",
- "t_order_9")).masterSlaveRules(masterSlaveRules).dataSourceRule(dataSourceRule).build();
+ "t_order_9")).dataSourceRule(dataSourceRule).build();
TableRule orderItemTableRule = TableRule.builder("t_order_item").actualTables(Arrays.asList(
"t_order_item_0",
"t_order_item_1",
@@ -136,13 +146,12 @@ protected final ShardingDataSource getShardingDataSource() {
"t_order_item_6",
"t_order_item_7",
"t_order_item_8",
- "t_order_item_9")).masterSlaveRules(masterSlaveRules).dataSourceRule(dataSourceRule).build();
+ "t_order_item_9")).dataSourceRule(dataSourceRule).build();
TableRule configRule = TableRule.builder("t_config").dataSourceRule(dataSourceRule).build();
ShardingRule shardingRule = ShardingRule.builder().dataSourceRule(dataSourceRule).tableRules(Arrays.asList(orderTableRule, orderItemTableRule, configRule))
.bindingTableRules(Collections.singletonList(new BindingTableRule(Arrays.asList(orderTableRule, orderItemTableRule))))
.databaseShardingStrategy(new DatabaseShardingStrategy("user_id", new SingleKeyModuloDatabaseShardingAlgorithm()))
- .tableShardingStrategy(new TableShardingStrategy("order_id", new SingleKeyModuloTableShardingAlgorithm()))
- .masterSlaveRules(masterSlaveRules).build();
+ .tableShardingStrategy(new TableShardingStrategy("order_id", new SingleKeyModuloTableShardingAlgorithm())).build();
return new ShardingDataSource(shardingRule);
}
}
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithDMLTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithDMLTest.java
index c8762abfdd57c..3a16bc0d07003 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithDMLTest.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithDMLTest.java
@@ -155,7 +155,7 @@ protected void assertDataSet(final String expectedDataSetPattern, final String s
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
assertDataSet(String.format("integrate/dataset/masterslave/expect/%s/master_%s.xml", expectedDataSetPattern, i),
- shardingDataSource.getConnection().getConnection(String.format("dataSource_master_%s", i), SQLStatementType.SELECT),
+ shardingDataSource.getConnection().getConnection(String.format("ms_%s", i), SQLStatementType.SELECT),
String.format("t_order_%s", j), String.format("SELECT * FROM `t_order_%s` WHERE `status`=?", j), status);
}
}
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithSelectTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithSelectTest.java
index 0abdcf4acca94..65520d4023c93 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithSelectTest.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithSelectTest.java
@@ -30,8 +30,9 @@ public class ShardingMasterSlaveForPStatementWithSelectTest extends AbstractShar
private ShardingDataSource shardingDataSource;
@Before
- public void init() throws SQLException {
+ public void init() throws SQLException, NoSuchFieldException, IllegalAccessException {
shardingDataSource = getShardingDataSource();
+ reset();
}
@Test
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/statement/ShardingMasterSlaveForStatementWithDMLTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/statement/ShardingMasterSlaveForStatementWithDMLTest.java
index e85b0a95015a8..a06e9354cf0ad 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/statement/ShardingMasterSlaveForStatementWithDMLTest.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/statement/ShardingMasterSlaveForStatementWithDMLTest.java
@@ -84,7 +84,7 @@ protected void assertDataSet(final String expectedDataSetPattern, final String s
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
assertDataSet(String.format("integrate/dataset/masterslave/expect/%s/master_%s.xml", expectedDataSetPattern, i),
- shardingDataSource.getConnection().getConnection(String.format("dataSource_master_%s", i), SQLStatementType.SELECT),
+ shardingDataSource.getConnection().getConnection(String.format("ms_%s", i), SQLStatementType.SELECT),
String.format("t_order_%s", j), String.format("SELECT * FROM `t_order_%s` WHERE `status`=?", j), status);
}
}
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/nullable/AbstractShardingNullableDBUnitTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/nullable/AbstractShardingNullableDBUnitTest.java
index b75c3ad2259c8..4fd5cf3dc1713 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/nullable/AbstractShardingNullableDBUnitTest.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/nullable/AbstractShardingNullableDBUnitTest.java
@@ -70,8 +70,8 @@ protected final ShardingDataSource getShardingDataSource() {
DataSourceRule dataSourceRule = new DataSourceRule(createDataSourceMap(dataSourceName));
TableRule orderTableRule = TableRule.builder("t_order").dataSourceRule(dataSourceRule).build();
- ShardingRule shardingRule = ShardingRule.builder().dataSourceRule(dataSourceRule).tableRules(Arrays.asList(orderTableRule))
- .bindingTableRules(Collections.singletonList(new BindingTableRule(Arrays.asList(orderTableRule))))
+ ShardingRule shardingRule = ShardingRule.builder().dataSourceRule(dataSourceRule).tableRules(Collections.singletonList(orderTableRule))
+ .bindingTableRules(Collections.singletonList(new BindingTableRule(Collections.singletonList(orderTableRule))))
.databaseShardingStrategy(new DatabaseShardingStrategy(Collections.singletonList("user_id"), new MultipleKeysModuloDatabaseShardingAlgorithm()))
.tableShardingStrategy(new TableShardingStrategy(Collections.singletonList("order_id"), new NoneTableShardingAlgorithm())).build();
return new ShardingDataSource(shardingRule);
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/AllApiTests.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/AllApiTests.java
index f9b7058a8c48c..8cb242fb5e1a3 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/AllApiTests.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/AllApiTests.java
@@ -21,7 +21,6 @@
import com.dangdang.ddframe.rdb.sharding.api.rule.DataNodeTest;
import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRuleTest;
import com.dangdang.ddframe.rdb.sharding.api.rule.DynamicDataNodeTest;
-import com.dangdang.ddframe.rdb.sharding.api.rule.MasterSlaveRuleTest;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRuleTest;
import com.dangdang.ddframe.rdb.sharding.api.rule.TableRuleTest;
import com.dangdang.ddframe.rdb.sharding.api.strategy.common.ShardingStrategyTest;
@@ -53,7 +52,7 @@
TableShardingStrategyTest.class,
NoneTableShardingAlgorithmTest.class,
HintManagerTest.class,
- MasterSlaveRuleTest.class,
+ MasterSlaveDataSourceFactoryTest.class,
RoundRobinSlaveLoadBalanceStrategyTest.class
})
public class AllApiTests {
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/MasterSlaveDataSourceFactoryTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/MasterSlaveDataSourceFactoryTest.java
new file mode 100644
index 0000000000000..90918ee756afa
--- /dev/null
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/MasterSlaveDataSourceFactoryTest.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;
+
+import com.dangdang.ddframe.rdb.sharding.fixture.TestDataSource;
+import com.dangdang.ddframe.rdb.sharding.jdbc.MasterSlaveDataSource;
+import org.junit.Test;
+
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.junit.Assert.assertThat;
+
+public final class MasterSlaveDataSourceFactoryTest {
+
+ @Test
+ public void assertCreateDataSourceForSingleSlave() {
+ assertThat(MasterSlaveDataSourceFactory.createDataSource("logic_ds", new TestDataSource("master_ds"), new TestDataSource("slave_ds")), instanceOf(MasterSlaveDataSource.class));
+ }
+
+ @Test
+ public void assertCreateDataSourceForMultipleSlaves() {
+ assertThat(MasterSlaveDataSourceFactory.createDataSource("logic_ds", new TestDataSource("master_ds"), new TestDataSource("slave_ds_0"), new TestDataSource("slave_ds_1")),
+ instanceOf(MasterSlaveDataSource.class));
+ }
+}
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataSourceRuleTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataSourceRuleTest.java
index 4469e728d2702..8d40f8e0c1e08 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataSourceRuleTest.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/DataSourceRuleTest.java
@@ -17,7 +17,7 @@
package com.dangdang.ddframe.rdb.sharding.api.rule;
-import com.dangdang.ddframe.rdb.sharding.api.rule.fixture.TestDataSource;
+import com.dangdang.ddframe.rdb.sharding.fixture.TestDataSource;
import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/MasterSlaveRuleTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/MasterSlaveRuleTest.java
deleted file mode 100644
index b56c4a7c45a4a..0000000000000
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/MasterSlaveRuleTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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 com.dangdang.ddframe.rdb.sharding.parser.result.router.SQLStatementType;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.lang.reflect.Field;
-import java.util.Arrays;
-import java.util.Collections;
-
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-public final class MasterSlaveRuleTest {
-
- private MasterSlaveRule masterSlaveRule = new MasterSlaveRule("test_ds", "test_ds_master", Collections.singletonList("test_ds_slave"));
-
- @Before
- @After
- public void reset() throws NoSuchFieldException, IllegalAccessException {
- Field field = MasterSlaveRule.class.getDeclaredField("WAS_UPDATED");
- field.setAccessible(true);
- ((ThreadLocal) field.get(MasterSlaveRule.class)).remove();
- }
-
- @Test
- public void assertGetMasterOrSlaveDataSourceForDML() {
- assertThat(masterSlaveRule.getMasterOrSlaveDataSource(SQLStatementType.INSERT), is("test_ds_master"));
- }
-
- @Test
- public void assertGetMasterOrSlaveDataSourceForDQL() {
- assertThat(masterSlaveRule.getMasterOrSlaveDataSource(SQLStatementType.SELECT), is("test_ds_slave"));
- }
-
- @Test
- public void assertGetMasterOrSlaveDataSourceForDMLAndDQL() {
- assertThat(masterSlaveRule.getMasterOrSlaveDataSource(SQLStatementType.INSERT), is("test_ds_master"));
- assertThat(masterSlaveRule.getMasterOrSlaveDataSource(SQLStatementType.SELECT), is("test_ds_master"));
- }
-
- @Test
- public void assertWithinForMaster() {
- assertTrue(masterSlaveRule.within("test_ds_master"));
- }
-
- @Test
- public void assertWithinForSlave() {
- assertTrue(masterSlaveRule.within("test_ds_slave"));
- }
-
- @Test
- public void assertNotWithin() {
- assertFalse(masterSlaveRule.within("test_ds"));
- }
-}
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/ShardingRuleTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/ShardingRuleTest.java
index 987e4ff70c82b..4a5c36312f040 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/ShardingRuleTest.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/ShardingRuleTest.java
@@ -202,26 +202,12 @@ public void assertGetAllShardingColumnsWithStrategy() {
assertThat(createShardingRuleWithStrategy().getAllShardingColumns(), is((Collection) Sets.newHashSet("column")));
}
- @Test
- public void assertFindMasterSlaveRule() {
- ShardingRule shardingRule = createShardingRule(
- Arrays.asList(new MasterSlaveRule("ds0", "ds0_master", Collections.singletonList("ds0_slave")), new MasterSlaveRule("ds1", "ds1_master", Arrays.asList("ds1_slave_1", "ds1_slave_2"))));
- assertThat(shardingRule.findMasterSlaveRule("ds0").get().getMasterDataSource(), is("ds0_master"));
- assertThat(shardingRule.findMasterSlaveRule("ds1").get().getMasterDataSource(), is("ds1_master"));
- assertFalse(shardingRule.findMasterSlaveRule("ds2").isPresent());
- }
private ShardingRule createShardingRule() {
return ShardingRule.builder().dataSourceRule(createDataSourceRule())
.tableRules(Collections.singletonList(createTableRule())).bindingTableRules(Collections.singletonList(createBindingTableRule())).build();
}
- private ShardingRule createShardingRule(final Collection masterSlaveRules) {
- return ShardingRule.builder().dataSourceRule(createDataSourceRule())
- .tableRules(Collections.singletonList(createTableRule())).bindingTableRules(Collections.singletonList(createBindingTableRule()))
- .masterSlaveRules(masterSlaveRules).build();
- }
-
private DataSourceRule createDataSourceRule() {
Map result = new HashMap<>(2);
result.put("ds0", null);
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/slave/RoundRobinSlaveLoadBalanceStrategyTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/slave/RoundRobinSlaveLoadBalanceStrategyTest.java
index 4586d1456f87b..d51503fcc1f4e 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/slave/RoundRobinSlaveLoadBalanceStrategyTest.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/strategy/slave/RoundRobinSlaveLoadBalanceStrategyTest.java
@@ -17,8 +17,10 @@
package com.dangdang.ddframe.rdb.sharding.api.strategy.slave;
+import com.dangdang.ddframe.rdb.sharding.fixture.TestDataSource;
import org.junit.Test;
+import javax.sql.DataSource;
import java.util.Arrays;
import static org.hamcrest.core.Is.is;
@@ -30,8 +32,10 @@ public final class RoundRobinSlaveLoadBalanceStrategyTest {
@Test
public void assertGetDataSource() {
- assertThat(roundRobinSlaveLoadBalanceStrategy.getDataSource("ds", Arrays.asList("ds_0", "ds_1")), is("ds_0"));
- assertThat(roundRobinSlaveLoadBalanceStrategy.getDataSource("ds", Arrays.asList("ds_0", "ds_1")), is("ds_1"));
- assertThat(roundRobinSlaveLoadBalanceStrategy.getDataSource("ds", Arrays.asList("ds_0", "ds_1")), is("ds_0"));
+ DataSource slaveDataSource1 = new TestDataSource("test_ds_slave_1");
+ DataSource slaveDataSource2 = new TestDataSource("test_ds_slave_2");
+ assertThat(roundRobinSlaveLoadBalanceStrategy.getDataSource("ds", Arrays.asList(slaveDataSource1, slaveDataSource2)), is(slaveDataSource1));
+ assertThat(roundRobinSlaveLoadBalanceStrategy.getDataSource("ds", Arrays.asList(slaveDataSource1, slaveDataSource2)), is(slaveDataSource2));
+ assertThat(roundRobinSlaveLoadBalanceStrategy.getDataSource("ds", Arrays.asList(slaveDataSource1, slaveDataSource2)), is(slaveDataSource1));
}
}
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/fixture/TestDataSource.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/fixture/TestDataSource.java
similarity index 83%
rename from sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/fixture/TestDataSource.java
rename to sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/fixture/TestDataSource.java
index e80dcd784e2d8..1de5c1af22d91 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/api/rule/fixture/TestDataSource.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/fixture/TestDataSource.java
@@ -15,7 +15,7 @@
*
*/
-package com.dangdang.ddframe.rdb.sharding.api.rule.fixture;
+package com.dangdang.ddframe.rdb.sharding.fixture;
import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractDataSourceAdapter;
import lombok.EqualsAndHashCode;
@@ -34,9 +34,4 @@ public final class TestDataSource extends AbstractDataSourceAdapter {
public Connection getConnection() throws SQLException {
return null;
}
-
- @Override
- public Connection getConnection(final String username, final String password) throws SQLException {
- return getConnection();
- }
}
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/AllJDBCTests.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/AllJDBCTests.java
index 2ab1151fbdcab..0568e30fd6afe 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/AllJDBCTests.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/AllJDBCTests.java
@@ -54,7 +54,8 @@
ResultSetGetterAdapterTest.class,
ResultSetAdapterTest.class,
JdbcMethodInvocationTest.class,
- RowSetResultSetAdapterTest.class
+ RowSetResultSetAdapterTest.class,
+ MasterSlaveDataSourceTest.class
})
public class AllJDBCTests {
}
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSourceTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSourceTest.java
new file mode 100644
index 0000000000000..7395ebeb9057a
--- /dev/null
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSourceTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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 com.dangdang.ddframe.rdb.sharding.fixture.TestDataSource;
+import com.dangdang.ddframe.rdb.sharding.parser.result.router.SQLStatementType;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.sql.DataSource;
+import java.lang.reflect.Field;
+import java.util.Collections;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public final class MasterSlaveDataSourceTest {
+
+ private DataSource masterDataSource = new TestDataSource("test_ds_master");
+
+ private DataSource slaveDataSource = new TestDataSource("test_ds_slave");
+
+ private MasterSlaveDataSource masterSlaveDataSource = new MasterSlaveDataSource("test_ds", masterDataSource, Collections.singletonList(slaveDataSource));
+
+ @Before
+ @After
+ public void reset() throws NoSuchFieldException, IllegalAccessException {
+ Field field = MasterSlaveDataSource.class.getDeclaredField("WAS_UPDATED");
+ field.setAccessible(true);
+ ((ThreadLocal) field.get(MasterSlaveDataSource.class)).remove();
+ }
+
+ @Test
+ public void assertGetDataSourceForDML() {
+ assertThat(masterSlaveDataSource.getDataSource(SQLStatementType.INSERT), is(masterDataSource));
+ }
+
+ @Test
+ public void assertGetDataSourceForDQL() {
+ assertThat(masterSlaveDataSource.getDataSource(SQLStatementType.SELECT), is(slaveDataSource));
+ }
+
+ @Test
+ public void assertGetDataSourceForDMLAndDQL() {
+ assertThat(masterSlaveDataSource.getDataSource(SQLStatementType.INSERT), is(masterDataSource));
+ assertThat(masterSlaveDataSource.getDataSource(SQLStatementType.SELECT), is(masterDataSource));
+ }
+}
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingDataSourceTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingDataSourceTest.java
index ce04145505936..b614ea0b8768c 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingDataSourceTest.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingDataSourceTest.java
@@ -47,14 +47,6 @@ public void assertGetConnection() throws SQLException {
assertThat(createShardingDataSource(dataSource).getConnection().getConnection("ds", SQLStatementType.SELECT), is(connection));
}
- @Test
- public void assertGetConnectionWithUsername() throws SQLException {
- Connection connection = mockConnection();
- DataSource dataSource = mock(DataSource.class);
- when(dataSource.getConnection()).thenReturn(connection);
- assertThat(createShardingDataSource(dataSource).getConnection("username", "password").getConnection("ds", SQLStatementType.SELECT), is(connection));
- }
-
private Connection mockConnection() throws SQLException {
Connection result = mock(Connection.class);
DatabaseMetaData databaseMetaData = mock(DatabaseMetaData.class);
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/DataSourceAdapterTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/DataSourceAdapterTest.java
index 872da7b525715..8d4eca7138e1e 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/DataSourceAdapterTest.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/adapter/DataSourceAdapterTest.java
@@ -32,6 +32,7 @@
import java.util.List;
import java.util.logging.Logger;
+import com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection;
import org.junit.Before;
import org.junit.Test;
@@ -93,4 +94,10 @@ public void assertSetLogWriter() throws SQLException {
public void assertGetParentLogger() throws SQLException {
assertThat(shardingDataSource.getParentLogger().getName(), is(Logger.GLOBAL_LOGGER_NAME));
}
+
+
+ @Test
+ public void assertGetConnectionWithUsername() throws SQLException {
+ assertThat(shardingDataSource.getConnection("username", "password"), instanceOf(ShardingConnection.class));
+ }
}
diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/fixture/MockResultSet.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/fixture/MockResultSet.java
index 9bc24356f530e..31b4dd7172c05 100644
--- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/fixture/MockResultSet.java
+++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/merger/fixture/MockResultSet.java
@@ -264,7 +264,7 @@ public String getColumnClassName(final int column) throws SQLException {
}
@Override
- public T unwrap(final Class iface) throws SQLException {
+ public I unwrap(final Class iface) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
diff --git a/sharding-jdbc-doc/content/index/index.md b/sharding-jdbc-doc/content/index/index.md
index 708ff6c0a3c8e..d26a2edde356a 100644
--- a/sharding-jdbc-doc/content/index/index.md
+++ b/sharding-jdbc-doc/content/index/index.md
@@ -5,11 +5,9 @@
* 曹昊 [当当](http://www.dangdang.com/) caohao@dangdang.com
* 岳令 [当当](http://www.dangdang.com/) yueling@dangdang.com
-**讨论QQ群:**532576663(不限于Sharding-JDBC,包括分布式,数据库相关以及其他互联网技术交流)
+**讨论QQ群:**532576663(不限于Sharding-JDBC,包括分布式,数据库相关以及其他互联网技术交流。由于QQ群已接近饱和,我们希望您在申请加群之前仔细阅读文档,并在加群申请中正确回答问题,以及在申请时写上您的姓名和公司名称。并且在入群后及时修改群名片。否则我们将有权拒绝您的入群申请。谢谢合作。)
# 简介
-`Sharding-JDBC`是当当应用框架`ddframe`中,关系型数据库模块`dd-rdb`中分离出来的数据库水平扩展框架,即透明化数据库分库分表访问。
-
`Sharding-JDBC`直接封装`JDBC API`,可以理解为增强版的`JDBC`驱动,旧代码迁移成本几乎为零:
* 可适用于任何基于`java`的`ORM`框架,如:`JPA`, `Hibernate`, `Mybatis`, `Spring JDBC Template`或直接使用`JDBC`。
@@ -22,6 +20,13 @@
* 分片策略灵活,可支持`=`,`BETWEEN`,`IN`等多维度分片,也可支持多分片键共用。
* `SQL`解析功能完善,支持聚合,分组,排序,`Limit`,`OR`等查询,并且支持`Binding Table`以及笛卡尔积的表查询。
+* 支持柔性事务(目前仅最大努力送达型)。
+* 支持读写分离。
+
+`Sharding-JDBC`配置多样:
+
+* 可支持YAML和Spring命名空间配置
+* 灵活多样的`inline`方式
***
@@ -57,13 +62,16 @@
## 规则配置
`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()));
+ShardingRule shardingRule = ShardingRule.builder()
+ .dataSourceRule(dataSourceRule)
+ .tableRules(tableRuleList)
+ .databaseShardingStrategy(new DatabaseShardingStrategy("sharding_column", new XXXShardingAlgorithm()))
+ .tableShardingStrategy(new TableShardingStrategy("sharding_column", new XXXShardingAlgorithm())))
+ .build();
```
+
规则配置包括数据源配置、表规则配置、分库策略和分表策略组成。这只是最简单的配置方式,实际使用可更加灵活,如:多分片键,分片策略直接和`tableRule`绑定等。
>详细的规则配置请参考[用户指南](post/user_guide)
@@ -71,6 +79,7 @@
## 使用基于ShardingDataSource的JDBC接口
通过`ShardingDataSourceFactory`工厂和规则配置对象获取`ShardingDataSource`,`ShardingDataSource`实现自`JDBC`的标准接口`DataSource`。然后可通过`DataSource`选择使用原生`JDBC`开发,或者使用`JPA`, `MyBatis`等`ORM`工具。
以`JDBC`原生实现为例:
+
```java
DataSource dataSource = ShardingDataSourceFactory.createDataSource(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=?";
@@ -83,9 +92,51 @@ try (
while(rs.next()) {
System.out.println(rs.getInt(1));
System.out.println(rs.getInt(2));
- System.out.println(rs.getInt(3));
}
}
}
```
+## 使用Spring命名空间配置
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
diff --git a/sharding-jdbc-doc/content/post/master_slave.md b/sharding-jdbc-doc/content/post/master_slave.md
index 34ad806ef69be..ad7023e906604 100644
--- a/sharding-jdbc-doc/content/post/master_slave.md
+++ b/sharding-jdbc-doc/content/post/master_slave.md
@@ -24,18 +24,14 @@ weight = 6
## 开发示例
```java
- // 构建读写分离规则
- Collection masterSlaveRules = new ArrayList<>(2);
- // ds_0, ds_1是读写分离逻辑数据源, ds_0_master, ds_0_slave_1等数据源是真实数据源
- masterSlaveRules.add(new MasterSlaveRule("ds_0", "ds_0_master", Arrays.asList("ds_0_slave_1", "ds_0_slave_2"));
- masterSlaveRules.add(new MasterSlaveRule("ds_1", "ds_1_master", Arrays.asList("ds_1_slave_1", "ds_1_slave_2"));
-
- ShardingRule shardingRule = ShardingRule.builder()
- .dataSourceRule(dataSourceRule)
- // 请注意, TableRule也需要通过builder传入Collection
- .tableRules(Arrays.asList(orderTableRule, orderItemTableRule))
- .databaseShardingStrategy(new DatabaseShardingStrategy("user_id", new ModuloDatabaseShardingAlgorithm()))
- .tableShardingStrategy(new TableShardingStrategy("order_id", new ModuloTableShardingAlgorithm()))
- .masterSlaveRules(masterSlaveRules)
- .build();
+// 构建读写分离数据源
+MasterSlaveDataSource masterSlaveDs0 = new MasterSlaveDataSourceFactory.createDataSource("ms_0", masterDataSource0, slaveDataSource00, slaveDataSource01);
+MasterSlaveDataSource masterSlaveDs1 = new MasterSlaveDataSourceFactory.createDataSource("ms_1", masterDataSource1, slaveDataSource11, slaveDataSource11);
+
+// 构建分库分表数据源
+Map dataSourceMap = new HashMap<>(2);
+dataSourceMap.put("ms_0", masterSlaveDs0);
+dataSourceMap.put("ms_1", masterSlaveDs1);
+
+// 通过ShardingDataSourceFactory继续创建ShardingDataSource
```