一、在最开始提到了GroupIDAndCollectTimeDBShardingAlgorithm分库策略和CollectTimeYYYYMMDDTBShardingAlgorithm分表策略
这两个分别实现的是MultipleKeysDatabaseShardingAlgorithm实现了dosharding方法
CollectTimeYYYYMMDDTBShardingAlgorithm实现了SingleKeyTableShardingAlgorithm中的
doEqualSharding ,doInSharding , doBetweenSharding三个方法分别匹配sql语句中的 = , in , between
具体的实现就不写了,因为分片策略不同的场景有着不同的策略,理解了自然就通了。
综合以上讲解:实现sharding-jdbc数据源可以分为以下流程
一、写好配置文件
①包括制定数据源的类,有可能是自己实现的数据源
public class SwitchableDruidDataSource extends DruidDataSource {
private static final Logger log = LoggerFactory.getLogger(SwitchableDruidDataSource.class);
private static int maxRetryTimes = 20;
private static int retryInterval = 10 * 1000;
@Override
public Connection createPhysicalConnection() throws SQLException {
if (!Boolean.valueOf(EmpfLocalConfigure.getValue("jdbc.ssl.switchable"))) {
return super.createPhysicalConnection();
}
int retryCounter = 0;
while (retryCounter < maxRetryTimes) {
try {
return super.createPhysicalConnection();
} catch (Exception ex) {
log.error("createPhysicalConnection error, ", ex);
try {
Thread.sleep(retryInterval);
} catch (InterruptedException e1) {
e1.printStackTrace();
LoggerFactory.getLogger(DruidDataSource.class).info("retry with url[{}] => ", retryCounter, this.getUrl());
}
retryCounter++;
switchSSL();
if (retryCounter >= maxRetryTimes) {
return super.createPhysicalConnection();
}
}
}
return null;
}
private void switchSSL() {
if (StringUtils.indexOf(getUrl(), "useSSL=true") != -1) {
this.setUrl(StringUtils.replace(getUrl(), "useSSL=true", "useSSL=false"));
this.setUrl(StringUtils.replace(getUrl(), "verifyServerCertificate=true", "verifyServerCertificate=false"));
} else if (StringUtils.indexOf(getUrl(), "useSSL=false") != -1) {
this.setUrl(StringUtils.replace(getUrl(), "useSSL=false", "useSSL=true"));
this.setUrl(StringUtils.replace(getUrl(), "verifyServerCertificate=false", "verifyServerCertificate=true"));
}
}
}
②写好数据源和逻辑表的分库分表策略:这个可参考前两篇文章
二,写sharding 数据源,这个数据源要继承dangdang的shardingdatasource
public class YamlShardingDataSource extends com.dangdang.ddframe.rdb.sharding.jdbc.ShardingDataSource {
private YamlConfig yamlConfig = null;
public YamlShardingDataSource(final File yamlFile) throws IOException {
// C_387386 NULL_RETURNS
super(new ShardingRuleBuilder(yamlFile.getName(), unmarshal(yamlFile)).build(), null != unmarshal(yamlFile) ? unmarshal(yamlFile).getProps() : null);
yamlConfig = unmarshal(yamlFile);
LoggerFactory.getLogger(YamlShardingDataSource.class).debug("debug ==> " + yamlFile.getCanonicalPath());
}
private static YamlConfig unmarshal(final File yamlFile) throws IOException {
try (FileInputStream fileInputStream = new FileInputStream(yamlFile);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8")) {
return new Yaml(new YamlShardingConstructor()).loadAs(inputStreamReader, YamlConfig.class);
}
}
public YamlConfig getYamlConfig() {
return yamlConfig;
}
}
其中YamlShardingConstructor:
package com.pinnet.sharding.datasource;
import com.pinnet.platform.common.configure.EmpfLocalConfigure;
import org.apache.commons.lang.StringUtils;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeId;
import org.yaml.snakeyaml.nodes.ScalarNode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class YamlShardingConstructor extends Constructor {
//yaml规范已有${},此处使用${{}}做标记
private static final Pattern placeHolderPattern = Pattern.compile("\\$\\{\\{([^}}]+)\\}\\}");
public YamlShardingConstructor() {
super(YamlConfig.class);
yamlClassConstructors.put(NodeId.scalar, new EncryptedConstructScalar());
}
/**
* YAML解析插入自定义逻辑
*/
private class EncryptedConstructScalar extends ConstructScalar {
public Object construct(Node node) {
if (node instanceof ScalarNode) {
String val = (String) constructScalar((ScalarNode) node);
//【安全特性简述】如果yaml中有${{}},则用EmpfLocalConfigure中的值替换
Matcher matcher = placeHolderPattern.matcher(val);
boolean replace = false;
while (matcher.find()) {
replace = true;
val = StringUtils.replace(val, matcher.group(0), EmpfLocalConfigure.getValue(matcher.group(1)));
}
if (replace) {
return val;
}
}
return super.construct(node);
}
}
}
yamlconifg
public class YamlConfig extends ShardingRuleConfig {
private Properties props = new Properties();
public Properties getProps() {
return props;
}
public void setProps(Properties props) {
this.props = props;
}
}
分片策略详解可以查看:https://blog.csdn.net/wuliusir/article/details/51090189
http://lalahei.iteye.com/blog/2326061