Skip to content

Commit

Permalink
fixed #172 adjust Spring and Yaml config for id generator
Browse files Browse the repository at this point in the history
  • Loading branch information
hanahmily authored and gaohongtao committed Nov 14, 2016
1 parent 7bd1a97 commit 14a7e40
Show file tree
Hide file tree
Showing 21 changed files with 480 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.dangdang.ddframe.rdb.sharding.config.common.internal.algorithm.ClosureDatabaseShardingAlgorithm;
import com.dangdang.ddframe.rdb.sharding.config.common.internal.algorithm.ClosureTableShardingAlgorithm;
import com.dangdang.ddframe.rdb.sharding.config.common.internal.parser.InlineParser;
import com.dangdang.ddframe.rdb.sharding.id.generator.IdGenerator;
import com.dangdang.ddframe.rdb.sharding.router.strategy.MultipleKeysShardingAlgorithm;
import com.dangdang.ddframe.rdb.sharding.router.strategy.ShardingAlgorithm;
import com.dangdang.ddframe.rdb.sharding.router.strategy.ShardingStrategy;
Expand Down Expand Up @@ -83,7 +84,11 @@ public ShardingRuleBuilder(final String logRoot, final ShardingRuleConfig shardi
public ShardingRule build() {
DataSourceRule dataSourceRule = buildDataSourceRule();
Collection<TableRule> tableRules = buildTableRules(dataSourceRule);
return ShardingRule.builder().dataSourceRule(dataSourceRule).tableRules(tableRules).bindingTableRules(buildBindingTableRules(tableRules))
com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule.ShardingRuleBuilder shardingRuleBuilder = ShardingRule.builder().dataSourceRule(dataSourceRule);
if (!Strings.isNullOrEmpty(shardingRuleConfig.getIdGeneratorClass())) {
shardingRuleBuilder.idGenerator(loadClass(shardingRuleConfig.getIdGeneratorClass(), IdGenerator.class));
}
return shardingRuleBuilder.tableRules(tableRules).bindingTableRules(buildBindingTableRules(tableRules))
.databaseShardingStrategy(buildShardingStrategy(shardingRuleConfig.getDefaultDatabaseStrategy(), DatabaseShardingStrategy.class))
.tableShardingStrategy(buildShardingStrategy(shardingRuleConfig.getDefaultTableStrategy(), TableShardingStrategy.class)).build();
}
Expand All @@ -109,11 +114,22 @@ private Collection<TableRule> buildTableRules(final DataSourceRule dataSourceRul
if (!Strings.isNullOrEmpty(tableRuleConfig.getDataSourceNames())) {
tableRuleBuilder.dataSourceNames(new InlineParser(tableRuleConfig.getDataSourceNames()).evaluate());
}
buildAutoIncrementColumn(tableRuleBuilder, tableRuleConfig);
result.add(tableRuleBuilder.build());
}
return result;
}

private void buildAutoIncrementColumn(final TableRule.TableRuleBuilder tableRuleBuilder, final TableRuleConfig tableRuleConfig) {
for (Entry<String, String> each : tableRuleConfig.getAutoIncrementColumns().entrySet()) {
if (null == each.getValue()) {
tableRuleBuilder.autoIncrementColumns(each.getKey());
} else {
tableRuleBuilder.autoIncrementColumns(each.getKey(), loadClass(each.getValue(), IdGenerator.class));
}
}
}

private Collection<BindingTableRule> buildBindingTableRules(final Collection<TableRule> tableRules) {
Collection<BindingTableRule> result = new ArrayList<>(shardingRuleConfig.getBindingTables().size());
for (BindingTableRuleConfig each : shardingRuleConfig.getBindingTables()) {
Expand Down Expand Up @@ -174,4 +190,13 @@ private <T extends ShardingStrategy> T buildShardingAlgorithmClassName(final Lis
return returnClass.isAssignableFrom(DatabaseShardingStrategy.class) ? (T) new DatabaseShardingStrategy(shardingColumns, (MultipleKeysDatabaseShardingAlgorithm) shardingAlgorithm)
: (T) new TableShardingStrategy(shardingColumns, (MultipleKeysTableShardingAlgorithm) shardingAlgorithm);
}

@SuppressWarnings("unchecked")
private <T> Class<? extends T> loadClass(final String className, final Class<T> superClass) {
try {
return (Class<? extends T>) Class.forName(className);
} catch (final ClassNotFoundException ex) {
throw new IllegalArgumentException(ex);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@

package com.dangdang.ddframe.rdb.sharding.config.common.api.config;

import lombok.Getter;
import lombok.Setter;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;

import lombok.Getter;
import lombok.Setter;

/**
* 分片规则配置.
Expand All @@ -46,4 +46,6 @@ public class ShardingRuleConfig {
private StrategyConfig defaultDatabaseStrategy;

private StrategyConfig defaultTableStrategy;

private String idGeneratorClass;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
import lombok.Getter;
import lombok.Setter;

import java.util.HashMap;
import java.util.Map;

/**
* 表规则配置.
*
Expand All @@ -38,4 +41,6 @@ public class TableRuleConfig {
private StrategyConfig databaseStrategy;

private StrategyConfig tableStrategy;

private Map<String, String> autoIncrementColumns = new HashMap<>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,26 @@ public void assertBuildFailureWhenAlgorithmNotExisted() {
shardingRuleConfig.setDefaultDatabaseStrategy(getDatabaseStrategyConfig("xxx.Algorithm"));
new ShardingRuleBuilder(shardingRuleConfig).build();
}
@Test(expected = IllegalArgumentException.class)
public void assertBuildFailureWhenAutoIncrementClassNotExisted() {
ShardingRuleConfig shardingRuleConfig = new ShardingRuleConfig();
shardingRuleConfig.setDataSource(createDataSourceMap());
shardingRuleConfig.setDefaultDataSourceName("ds_0");
shardingRuleConfig.setTables(createTableRuleConfigMap());
shardingRuleConfig.setIdGeneratorClass("not.existed");
shardingRuleConfig.setBindingTables(Collections.singletonList(createBindingTableRule("t_order", "t_order_item")));
shardingRuleConfig.setDefaultDatabaseStrategy(getDatabaseStrategyConfig(SingleAlgorithm.class.getName()));
shardingRuleConfig.setDefaultTableStrategy(getTableStrategyConfigForAlgorithmClass());
new ShardingRuleBuilder(shardingRuleConfig).build();
}

@Test
public void assertBuildSuccess() {
ShardingRuleConfig shardingRuleConfig = new ShardingRuleConfig();
shardingRuleConfig.setDataSource(createDataSourceMap());
shardingRuleConfig.setDefaultDataSourceName("ds_0");
shardingRuleConfig.setTables(createTableRuleConfigMap());
shardingRuleConfig.setIdGeneratorClass("com.dangdang.ddframe.rdb.sharding.config.common.fixture.IncrementIdGenerator");
shardingRuleConfig.setBindingTables(Collections.singletonList(createBindingTableRule("t_order", "t_order_item")));
shardingRuleConfig.setDefaultDatabaseStrategy(getDatabaseStrategyConfig(SingleAlgorithm.class.getName()));
shardingRuleConfig.setDefaultTableStrategy(getTableStrategyConfigForAlgorithmClass());
Expand Down Expand Up @@ -144,6 +157,10 @@ private TableRuleConfig createTableRuleConfig(final String logicTable) {
result.setDataSourceNames("ds_${0..1}");
result.setDatabaseStrategy(getDatabaseStrategyConfig(SingleAlgorithm.class.getName()));
result.setTableStrategy(getTableStrategyConfigForExpression());
Map<String, String> autoIncrementColumnMap = new HashMap<>();
autoIncrementColumnMap.put("order_id", null);
autoIncrementColumnMap.put("order_item_id", "com.dangdang.ddframe.rdb.sharding.config.common.fixture.DecrementIdGenerator");
result.setAutoIncrementColumns(autoIncrementColumnMap);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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.config.common.fixture;

import com.dangdang.ddframe.rdb.sharding.id.generator.IdGenerator;

import java.util.concurrent.atomic.AtomicInteger;

abstract class AbstractNumberIdGenerator implements IdGenerator{

final AtomicInteger sequence = new AtomicInteger(100);

@Override
public void initContext(final String tableName, final String columnName) {

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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.config.common.fixture;

public class DecrementIdGenerator extends AbstractNumberIdGenerator{

@Override
public Object generateId() {
return sequence.decrementAndGet();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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.config.common.fixture;

public class IncrementIdGenerator extends AbstractNumberIdGenerator{

@Override
public Object generateId() {
return sequence.incrementAndGet();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,12 @@ public final class ShardingJdbcDataSourceBeanDefinitionParserTag {
public static final String DEFAULT_DATABASE_STRATEGY_ATTRIBUTE = "default-database-strategy";

public static final String DEFAULT_TABLE_STRATEGY_ATTRIBUTE = "default-table-strategy";

public static final String AUTO_INCREMENT_COLUMN = "auto-increment-column";

public static final String COLUMN_NAME = "column-name";

public static final String COLUMN_ID_GENERATOR_CLASS = "column-id-generator-class";

public static final String ID_GENERATOR_CLASS = "id-generator-class";
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,17 @@ private BeanDefinition parseShardingRuleConfig(final Element element, final Pars
factory.addPropertyValue("bindingTables", parseBindingTablesConfig(shardingRuleElement));
factory.addPropertyValue("defaultDatabaseStrategy", parseDefaultDatabaseStrategyConfig(shardingRuleElement));
factory.addPropertyValue("defaultTableStrategy", parseDefaultTableStrategyConfig(shardingRuleElement));
parseIdGenerator(factory, shardingRuleElement);
return factory.getBeanDefinition();
}

private void parseIdGenerator(final BeanDefinitionBuilder factory, final Element element) {
String idGeneratorClass = element.getAttribute(ShardingJdbcDataSourceBeanDefinitionParserTag.ID_GENERATOR_CLASS);
if (!Strings.isNullOrEmpty(idGeneratorClass)) {
factory.addPropertyValue("idGeneratorClass", idGeneratorClass);
}
}

private Map<String, BeanDefinition> parseDataSources(final Element element, final ParserContext parserContext) {
List<String> dataSources = Splitter.on(",").trimResults().splitToList(element.getAttribute(ShardingJdbcDataSourceBeanDefinitionParserTag.DATA_SOURCES_TAG));
Map<String, BeanDefinition> result = new ManagedMap<>(dataSources.size());
Expand Down Expand Up @@ -116,6 +124,16 @@ private BeanDefinition parseTableRuleConfig(final Element tableElement) {
if (!Strings.isNullOrEmpty(tableStrategy)) {
factory.addPropertyReference("tableStrategy", tableStrategy);
}
List<Element> autoIncrementColumns = DomUtils.getChildElementsByTagName(tableElement, ShardingJdbcDataSourceBeanDefinitionParserTag.AUTO_INCREMENT_COLUMN);
if (null == autoIncrementColumns || autoIncrementColumns.isEmpty()) {
return factory.getBeanDefinition();
}
Map<String, String> autoIncrementColumnMap = new ManagedMap<>(autoIncrementColumns.size());
for (Element each : autoIncrementColumns) {
autoIncrementColumnMap.put(each.getAttribute(ShardingJdbcDataSourceBeanDefinitionParserTag.COLUMN_NAME),
Strings.emptyToNull(each.getAttribute(ShardingJdbcDataSourceBeanDefinitionParserTag.COLUMN_ID_GENERATOR_CLASS)));
}
factory.addPropertyValue("autoIncrementColumns", autoIncrementColumnMap);
return factory.getBeanDefinition();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
</xsd:sequence>
<xsd:attribute name="data-sources" type="xsd:string" use="required" />
<xsd:attribute name="default-data-source" type="xsd:string" use="optional" />
<xsd:attribute name="id-generator-class" type="xsd:string" use="optional" />
</xsd:complexType>
</xsd:element>
<xsd:element name="table-rules">
Expand All @@ -36,6 +37,9 @@
</xsd:element>
<xsd:element name="table-rule">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="auto-increment-column" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="logic-table" type="xsd:string" use="required" />
<xsd:attribute name="dynamic" type="xsd:string" use="optional" />
<xsd:attribute name="actual-tables" type="xsd:string" use="optional" />
Expand All @@ -44,6 +48,12 @@
<xsd:attribute name="table-strategy" type="xsd:string" use="optional" />
</xsd:complexType>
</xsd:element>
<xsd:element name="auto-increment-column">
<xsd:complexType>
<xsd:attribute name="column-name" type="xsd:string" use="required"/>
<xsd:attribute name="column-id-generator-class" type="xsd:string" use="optional"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="binding-table-rules">
<xsd:complexType>
<xsd:sequence>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.dangdang.ddframe.rdb.sharding;

import com.dangdang.ddframe.rdb.sharding.spring.AutoIncrementDBUnitTest;
import com.dangdang.ddframe.rdb.sharding.spring.cases.WithoutNamespaceDefaultStrategyTest;
import com.dangdang.ddframe.rdb.sharding.spring.cases.WithoutNamespaceTest;
import com.dangdang.ddframe.rdb.sharding.spring.cases.namespace.WithNamespaceAlgorithmClassAndPropsTest;
Expand Down Expand Up @@ -45,7 +46,8 @@
WithoutNamespaceDefaultStrategyTest.class,
WithNamespaceDifferentTablesTest.class,
WithNamespaceForIndicatedDataSourceNamesTest.class,
WithNamespaceForMasterSlaveTest.class
WithNamespaceForMasterSlaveTest.class,
AutoIncrementDBUnitTest.class,
})
public class AllSpringTests {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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;

import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

@ContextConfiguration(locations = "classpath:META-INF/rdb/namespace/withNamespaceAutoIncrementColumns.xml")
public class AutoIncrementDBUnitTest extends AbstractSpringDBUnitTest{

@Test
public void test() throws SQLException {
try (Connection connection = getShardingDataSource().getConnection();
Statement statement = connection.createStatement()) {
statement.execute("INSERT INTO `t_order` (`user_id`, `status`) VALUES (1, 'init')", Statement.RETURN_GENERATED_KEYS);
assertTrue(statement.getGeneratedKeys().next());
assertEquals(statement.getGeneratedKeys().getLong(1), 101L);
statement.execute("INSERT INTO `t_order_item` (`order_id`, `user_id`, `status`) VALUES (101, 1, 'init')", Statement.RETURN_GENERATED_KEYS);
assertTrue(statement.getGeneratedKeys().next());
assertEquals(statement.getGeneratedKeys().getLong(1), 99L);
}
}
}
Loading

0 comments on commit 14a7e40

Please sign in to comment.