达梦数据库使用ShardingSphere

发布时间 2023-05-09 14:29:13作者: 闲人鹤

 

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;
    }