达梦数据库使用ShardingSphere
ShardingSphere只支持主流数据库,国产的数据库并不支持,就比如达梦数据库,所以我们自己扩展。
1. 下载 shardingsphere源码
下载地址:https://github.com/apache/shardingsphere
进入网址后,选择自己使用的 Tags 分支,并下载代码。我使用的版本是 4.0.0-RC2
再下载代码,目前支持 git clone,和 zip 压缩包下载。
2. 达梦扩展
在 sharding-core-common 模块下
实现 org.apache.shardingsphere.spi.database.DataSourceMetaData 接口,实现类写到 org.apache.shardingsphere.core.metadata.datasource.dialect 目录下
实现 org.apache.shardingsphere.spi.database.BranchDatabaseType 接口,实现类写到 org.apache.shardingsphere.core.spi.database 目录下
package org.apache.shardingsphere.core.spi.database; import org.apache.shardingsphere.core.database.DatabaseTypes; import org.apache.shardingsphere.core.metadata.datasource.dialect.DMDataSourceMetaData; import org.apache.shardingsphere.spi.database.BranchDatabaseType; import org.apache.shardingsphere.spi.database.DataSourceMetaData; import org.apache.shardingsphere.spi.database.DatabaseType; import java.util.Collection; import java.util.Collections; /** * @author zhanghe */ public class DMDatabaseType implements BranchDatabaseType { @Override public String getName() { return "DM"; } @Override public Collection<String> getJdbcUrlPrefixAlias() { return Collections.emptyList(); } @Override public DataSourceMetaData getDataSourceMetaData(String url) { return new DMDataSourceMetaData(url); } // sql解析等操作使用MySQL的实现 @Override public DatabaseType getTrunkDatabaseType() { return DatabaseTypes.getActualDatabaseType("MySQL"); } }
关于 getTrunkDatabaseType 方法,要说明一下,这里我们使用的MySQL的实现解析SQL,当然也可以选择 Oracle 等其他数据库,如果需要自己来实现,就需要在 sharding-core-parse下创建自己的module
本来还想着一个微服务同时支持MySQL和达梦库的,但发现sharding并不支持不同数据库类型的垂直分库,报错信息如下:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'shardingDataSource' defined in class path resource [org/apache/shardingsphere/shardingjdbc/spring/boot/SpringBootConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'shardingDataSource' threw exception; nested exception is java.lang.IllegalStateException: Database type inconsistent with 'org.apache.shardingsphere.core.spi.database.DMDatabaseType@1cec219f' and 'org.apache.shardingsphere.core.spi.database.MySQLDatabaseType@2b289ac9'
我同时看了4.0.0-RC2、4.1.1、5.1.0 这三个版本,判断数据库类型的代码在不同的版本中,位置是不一样的,我就不贴类了,报错代码如下:
dataSourceMap 是已加载的多个数据源,把判断出类型的第一个数据源类型存到了 result 里,再用 result 对比后面的数据源,如果不同就会报错。
private DatabaseType createDatabaseType() throws SQLException { DatabaseType result = null; for (DataSource each : dataSourceMap.values()) { DatabaseType databaseType = createDatabaseType(each); Preconditions.checkState(null == result || result == databaseType, String.format("Database type inconsistent with '%s' and '%s'", result, databaseType)); result = databaseType; } return result; }