Skip to content

Commit

Permalink
for #85 master slave spring namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
terrymanu committed May 30, 2016
1 parent 1303d55 commit 97e2e1f
Show file tree
Hide file tree
Showing 21 changed files with 387 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 1999-2015 dangdang.com.
* <p>
* 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.
* </p>
*/

package com.dangdang.ddframe.rdb.sharding.spring.namespace.constants;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
* 读写分离解析标签.
*
* @author zhangliang
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class MasterSlaveDataSourceBeanDefinitionParserTag {

public static final String MASTER_DATA_SOURCE_REF_ATTR = "master-data-source-ref";

public static final String SLAVE_DATA_SOURCES_REF_ATTR = "slave-data-sources-ref";
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.dangdang.ddframe.rdb.sharding.spring.namespace.handler;

import com.dangdang.ddframe.rdb.sharding.spring.namespace.parser.MasterSlaveDataSourceBeanDefinitionParser;
import com.dangdang.ddframe.rdb.sharding.spring.namespace.parser.ShardingJdbcDataSourceBeanDefinitionParser;
import com.dangdang.ddframe.rdb.sharding.spring.namespace.parser.ShardingJdbcStrategyBeanDefinitionParser;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
Expand All @@ -25,12 +26,14 @@
* Spring命名空间处理器.
*
* @author caohao
* @author zhangliang
*/
public final class ShardingJdbcNamespaceHandler extends NamespaceHandlerSupport {

@Override
public void init() {
registerBeanDefinitionParser("strategy", new ShardingJdbcStrategyBeanDefinitionParser());
registerBeanDefinitionParser("data-source", new ShardingJdbcDataSourceBeanDefinitionParser());
registerBeanDefinitionParser("master-slave-data-source", new MasterSlaveDataSourceBeanDefinitionParser());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 1999-2015 dangdang.com.
* <p>
* 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.
* </p>
*/

package com.dangdang.ddframe.rdb.sharding.spring.namespace.parser;

import com.dangdang.ddframe.rdb.sharding.jdbc.MasterSlaveDataSource;
import com.dangdang.ddframe.rdb.sharding.spring.namespace.constants.MasterSlaveDataSourceBeanDefinitionParserTag;
import com.google.common.base.Splitter;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;

import java.util.List;

/**
* 基于Spring命名空间的读写分离数据源解析器.
*
* @author zhangliang
*/
public class MasterSlaveDataSourceBeanDefinitionParser extends AbstractBeanDefinitionParser {

@Override
//CHECKSTYLE:OFF
protected AbstractBeanDefinition parseInternal(final Element element, final ParserContext parserContext) {
//CHECKSTYLE:ON
BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(MasterSlaveDataSource.class);
factory.addConstructorArgValue(element.getAttribute(ID_ATTRIBUTE));
factory.addConstructorArgReference(element.getAttribute(MasterSlaveDataSourceBeanDefinitionParserTag.MASTER_DATA_SOURCE_REF_ATTR));
factory.addConstructorArgValue(parseSlaveDataSources(element, parserContext));
return factory.getBeanDefinition();
}

private List<BeanDefinition> parseSlaveDataSources(final Element element, final ParserContext parserContext) {
List<String> slaveDataSources = Splitter.on(",").trimResults().splitToList(element.getAttribute(MasterSlaveDataSourceBeanDefinitionParserTag.SLAVE_DATA_SOURCES_REF_ATTR));
List<BeanDefinition> result = new ManagedList<>(slaveDataSources.size());
for (String each : slaveDataSources) {
result.add(parserContext.getRegistry().getBeanDefinition(each));
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ protected AbstractBeanDefinition parseInternal(final Element element, final Pars
factory.addConstructorArgValue(parseProperties(element, parserContext));
return factory.getBeanDefinition();
}

private BeanDefinition parseShardingRuleConfig(final Element element, final ParserContext parserContext) {
Element shardingRuleElement = DomUtils.getChildElementByTagName(element, ShardingJdbcDataSourceBeanDefinitionParserTag.SHARDING_RULE_CONFIG_TAG);
BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(ShardingRuleConfig.class);
Expand All @@ -69,7 +69,7 @@ private BeanDefinition parseShardingRuleConfig(final Element element, final Pars
}

private Map<String, BeanDefinition> parseDataSources(final Element element, final ParserContext parserContext) {
List<String> dataSources = Splitter.on(",").splitToList(element.getAttribute(ShardingJdbcDataSourceBeanDefinitionParserTag.DATA_SOURCES_TAG));
List<String> dataSources = Splitter.on(",").trimResults().splitToList(element.getAttribute(ShardingJdbcDataSourceBeanDefinitionParserTag.DATA_SOURCES_TAG));
Map<String, BeanDefinition> result = new ManagedMap<>(dataSources.size());
for (String each : dataSources) {
result.put(each, parserContext.getRegistry().getBeanDefinition(each));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,11 @@
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="master-slave-data-source">
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="required" />
<xsd:attribute name="master-data-source-ref" type="xsd:string" use="required" />
<xsd:attribute name="slave-data-sources-ref" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:schema>
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.dangdang.ddframe.rdb.sharding.spring.cases.namespace.WithNamespaceDefaultStrategyTest;
import com.dangdang.ddframe.rdb.sharding.spring.cases.namespace.WithNamespaceDifferentTablesTest;
import com.dangdang.ddframe.rdb.sharding.spring.cases.namespace.WithNamespaceForIndicatedDataSourceNamesTest;
import com.dangdang.ddframe.rdb.sharding.spring.cases.namespace.WithNamespaceForMasterSlaveTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
Expand All @@ -43,7 +44,8 @@
WithoutNamespaceTest.class,
WithoutNamespaceDefaultStrategyTest.class,
WithNamespaceDifferentTablesTest.class,
WithNamespaceForIndicatedDataSourceNamesTest.class
WithNamespaceForIndicatedDataSourceNamesTest.class,
WithNamespaceForMasterSlaveTest.class
})
public class AllSpringTests {
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,27 +99,4 @@ private void selectData() throws SQLException {
preparedStatement.close();
}
}

// private void selectDefaultData() throws SQLException {
// String sql = "SELECT * FROM `t_config`";
// try (Connection connection = getShardingDataSource().getConnection()) {
// PreparedStatement preparedStatement = connection.prepareStatement(sql);
// preparedStatement.setInt(1, 1);
// preparedStatement.setInt(2, 1);
// preparedStatement.setInt(3, 1);
// ResultSet resultSet = preparedStatement.executeQuery();
// int count = 0;
// while (resultSet.next()) {
// if (0 == count) {
// assertThat(resultSet.getInt(1), is(1));
// assertThat(resultSet.getInt(2), is(5));
// } else if (1 == count) {
// assertThat(resultSet.getInt(1), is(1));
// assertThat(resultSet.getInt(2), is(1));
// }
// count++;
// }
// preparedStatement.close();
// }
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ private String getFileName(final String dataSetFile) {
return fileName.substring(0, fileName.lastIndexOf("."));
}

private List<String> getSchemaFiles() {
protected List<String> getSchemaFiles() {
return Arrays.asList("schema/dbtbl_0.sql", "schema/dbtbl_1.sql");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 1999-2015 dangdang.com.
* <p>
* 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.
* </p>
*/

package com.dangdang.ddframe.rdb.sharding.spring.cases.namespace;

import com.dangdang.ddframe.rdb.sharding.spring.AbstractShardingBothDataBasesAndTablesSpringDBUnitTest;
import org.springframework.test.context.ContextConfiguration;

import java.util.Arrays;
import java.util.List;

@ContextConfiguration(locations = "classpath:META-INF/rdb/namespace/withNamespaceForMasterSlave.xml")
public final class WithNamespaceForMasterSlaveTest extends AbstractShardingBothDataBasesAndTablesSpringDBUnitTest {

@Override
protected List<String> getSchemaFiles() {
return Arrays.asList("schema/dbtbl_0_master.sql", "schema/dbtbl_0_slave_0.sql", "schema/dbtbl_0_slave_1.sql",
"schema/dbtbl_1_master.sql", "schema/dbtbl_1_slave_0.sql", "schema/dbtbl_1_slave_1.sql");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
<context:property-placeholder location="classpath:conf/rdb/conf.properties" ignore-unresolvable="true"/>

<bean id="dbtbl_0" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${dbtbl_0.driver}"/>
<property name="url" value="${dbtbl_0.url}"/>
<property name="username" value="${dbtbl_0.username}"/>
<property name="password" value="${dbtbl_0.password}"/>
<property name="driverClassName" value="${dbtbl_0.driver}"/>
<property name="url" value="${dbtbl_0.url}"/>
<property name="username" value="${dbtbl_0.username}"/>
<property name="password" value="${dbtbl_0.password}"/>
</bean>

<bean id="dbtbl_1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${dbtbl_1.driver}"/>
<property name="url" value="${dbtbl_1.url}"/>
<property name="username" value="${dbtbl_1.username}"/>
<property name="password" value="${dbtbl_1.password}"/>
<property name="driverClassName" value="${dbtbl_1.driver}"/>
<property name="url" value="${dbtbl_1.url}"/>
<property name="username" value="${dbtbl_1.username}"/>
<property name="password" value="${dbtbl_1.password}"/>
</bean>
</beans>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<context:property-placeholder location="classpath:conf/rdb/master_slave_conf.properties" ignore-unresolvable="true"/>

<bean id="dbtbl_0_master" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${dbtbl_0_master.driver}"/>
<property name="url" value="${dbtbl_0_master.url}"/>
<property name="username" value="${dbtbl_0_master.username}"/>
<property name="password" value="${dbtbl_0_master.password}"/>
</bean>

<bean id="dbtbl_0_slave_0" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${dbtbl_0_slave_0.driver}"/>
<property name="url" value="${dbtbl_0_slave_0.url}"/>
<property name="username" value="${dbtbl_0_slave_0.username}"/>
<property name="password" value="${dbtbl_0_slave_0.password}"/>
</bean>

<bean id="dbtbl_0_slave_1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${dbtbl_0_slave_1.driver}"/>
<property name="url" value="${dbtbl_0_slave_1.url}"/>
<property name="username" value="${dbtbl_0_slave_1.username}"/>
<property name="password" value="${dbtbl_0_slave_1.password}"/>
</bean>


<bean id="dbtbl_1_master" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${dbtbl_0_master.driver}"/>
<property name="url" value="${dbtbl_1_master.url}"/>
<property name="username" value="${dbtbl_1_master.username}"/>
<property name="password" value="${dbtbl_1_master.password}"/>
</bean>

<bean id="dbtbl_1_slave_0" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${dbtbl_0_slave_0.driver}"/>
<property name="url" value="${dbtbl_1_slave_0.url}"/>
<property name="username" value="${dbtbl_1_slave_0.username}"/>
<property name="password" value="${dbtbl_1_slave_0.password}"/>
</bean>

<bean id="dbtbl_1_slave_1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${dbtbl_1_slave_1.driver}"/>
<property name="url" value="${dbtbl_1_slave_1.url}"/>
<property name="username" value="${dbtbl_1_slave_1.username}"/>
<property name="password" value="${dbtbl_1_slave_1.password}"/>
</bean>
</beans>
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
http://www.dangdang.com/schema/ddframe/rdb/rdb.xsd
">
<import resource="../datasource/dataSource.xml" />

<rdb:strategy id="databaseStrategy" sharding-columns="user_id" algorithm-expression="dbtbl_${user_id.longValue() % 2}"/>

<rdb:strategy id="orderTableStrategy" sharding-columns="order_id" algorithm-expression="t_order_${order_id.longValue() % 4}"/>

<rdb:strategy id="orderItemTableStrategy" sharding-columns="order_id" algorithm-expression="t_order_item_${order_id.longValue() % 4}"/>

<rdb:data-source id="shardingDataSource">
<rdb:sharding-rule data-sources="dbtbl_0,dbtbl_1" default-data-source="dbtbl_0">
<rdb:table-rules>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rdb="http://www.dangdang.com/schema/ddframe/rdb"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.dangdang.com/schema/ddframe/rdb
http://www.dangdang.com/schema/ddframe/rdb/rdb.xsd
">
<import resource="../datasource/masterSlaveDataSource.xml" />

<rdb:master-slave-data-source id="dbtbl_0" master-data-source-ref="dbtbl_0_master" slave-data-sources-ref="dbtbl_0_slave_0, dbtbl_0_slave_1" />
<rdb:master-slave-data-source id="dbtbl_1" master-data-source-ref="dbtbl_1_master" slave-data-sources-ref="dbtbl_1_slave_0, dbtbl_1_slave_1" />

<rdb:strategy id="databaseStrategy" sharding-columns="user_id" algorithm-expression="dbtbl_${user_id.longValue() % 2}"/>

<rdb:strategy id="orderTableStrategy" sharding-columns="order_id" algorithm-expression="t_order_${order_id.longValue() % 4}"/>

<rdb:strategy id="orderItemTableStrategy" sharding-columns="order_id" algorithm-expression="t_order_item_${order_id.longValue() % 4}"/>

<rdb:data-source id="shardingDataSource">
<rdb:sharding-rule data-sources="dbtbl_0,dbtbl_1" default-data-source="dbtbl_0">
<rdb:table-rules>
<rdb:table-rule logic-table="t_order" actual-tables="t_order_${0..3}, t_order_${0..3}" data-source-names="dbtbl_0, dbtbl_1" database-strategy="databaseStrategy" table-strategy="orderTableStrategy"/>
<rdb:table-rule logic-table="t_order_item" actual-tables="t_order_item_${0..3}" data-source-names="dbtbl_${0..1}" database-strategy="databaseStrategy" table-strategy="orderItemTableStrategy"/>
</rdb:table-rules>
</rdb:sharding-rule>
</rdb:data-source>
</beans>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
dbtbl_0_master.driver=org.h2.Driver
dbtbl_0_master.url=jdbc:h2:mem:dbtbl_0_master;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL
dbtbl_0_master.username=sa
dbtbl_0_master.password=

dbtbl_0_slave_0.driver=org.h2.Driver
dbtbl_0_slave_0.url=jdbc:h2:mem:dbtbl_0_slave_0;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL
dbtbl_0_slave_0.username=sa
dbtbl_0_slave_0.password=

dbtbl_0_slave_1.driver=org.h2.Driver
dbtbl_0_slave_1.url=jdbc:h2:mem:dbtbl_0_slave_1;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL
dbtbl_0_slave_1.username=sa
dbtbl_0_slave_1.password=


dbtbl_1_master.driver=org.h2.Driver
dbtbl_1_master.url=jdbc:h2:mem:dbtbl_1_master;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL
dbtbl_1_master.username=sa
dbtbl_1_master.password=

dbtbl_1_slave_0.driver=org.h2.Driver
dbtbl_1_slave_0.url=jdbc:h2:mem:dbtbl_1_slave_0;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL
dbtbl_1_slave_0.username=sa
dbtbl_1_slave_0.password=

dbtbl_1_slave_1.driver=org.h2.Driver
dbtbl_1_slave_1.url=jdbc:h2:mem:dbtbl_1_slave_1;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL
dbtbl_1_slave_1.username=sa
dbtbl_1_slave_1.password=
Loading

0 comments on commit 97e2e1f

Please sign in to comment.