shardingSphere5.1.1 适配人大金仓

shardingSphere5.1.1 适配人大金仓

编译后的jar文件源码下载

1. 官网适配数据库说明

 图例可见,官网不支持人大金仓国产数据库,若要使用shardingSphere需要修改源码

2. 需要修改的类

2.1 KingBase8DatabaseType.java

java 复制代码
package org.apache.shardingsphere.infra.database.type.dialect;

import org.apache.shardingsphere.infra.database.metadata.dialect.KingBase8DataSourceMetaData;
import org.apache.shardingsphere.infra.database.type.BranchDatabaseType;
import org.apache.shardingsphere.infra.database.type.DatabaseType;
import org.apache.shardingsphere.infra.database.type.DatabaseTypeRegistry;
import org.apache.shardingsphere.sql.parser.sql.common.constant.QuoteCharacter;

import java.sql.Connection;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;

/**
 * Database type of KingBase.
 */
public final class KingBase8DatabaseType implements BranchDatabaseType {

    @Override
    public String getName() {
        return "kingbase8";
    }

    @Override
    public QuoteCharacter getQuoteCharacter() {
        return QuoteCharacter.QUOTE;
    }

    @Override
    public Collection<String> getJdbcUrlPrefixes() {
        return Collections.singleton(String.format("jdbc:%s:", getName().toLowerCase()));
    }

    @Override
    public KingBase8DataSourceMetaData getDataSourceMetaData(final String url, final String username) {
        return new KingBase8DataSourceMetaData(url);
    }

    @Override
    public Optional<String> getDataSourceClassName() {
        return Optional.empty();
    }

    @Override
    public Map<String, Collection<String>> getSystemDatabaseSchemaMap() {
        return Collections.emptyMap();
    }

    @Override
    public Collection<String> getSystemSchemas() {
        return Collections.emptyList();
    }

    @Override
    public String getSchema(final Connection connection) {
        return "public";
    }

    @Override
    public DatabaseType getTrunkDatabaseType() {
        return DatabaseTypeRegistry.getActualDatabaseType("MySQL");
    }

}

2.2 在META-INFO/services配置文件文件中添加配置,加载文件

2.3 KingBase8DataSourceMetaData.java

java 复制代码
package org.apache.shardingsphere.infra.database.metadata.dialect;

import lombok.Getter;
import org.apache.shardingsphere.infra.database.metadata.DataSourceMetaData;
import org.apache.shardingsphere.infra.database.metadata.url.JdbcUrl;
import org.apache.shardingsphere.infra.database.metadata.url.StandardJdbcUrlParser;

import java.util.Properties;

/**
 * Data source meta data for KingBase.
 */
@Getter
public class KingBase8DataSourceMetaData implements DataSourceMetaData {
    private static final int DEFAULT_PORT = 54321;

    private final String hostname;

    private final int port;

    private final String catalog;

    private final String schema;

    private final Properties queryProperties;

    private final Properties defaultQueryProperties = new Properties();

    public KingBase8DataSourceMetaData(final String url) {
        JdbcUrl jdbcUrl = new StandardJdbcUrlParser().parse(url);
        hostname = jdbcUrl.getHostname();
        port = -1 == jdbcUrl.getPort() ? DEFAULT_PORT : jdbcUrl.getPort();
        catalog = jdbcUrl.getDatabase();
        schema = "public";
        queryProperties = jdbcUrl.getQueryProperties();
    }

    @Override
    public Properties getDefaultQueryProperties() {
        return new Properties();
    }

    private void buildDefaultQueryProperties() {
        defaultQueryProperties.setProperty("useServerPrepStmts", Boolean.TRUE.toString());
        defaultQueryProperties.setProperty("cachePrepStmts", Boolean.TRUE.toString());
        defaultQueryProperties.setProperty("prepStmtCacheSize", "200000");
        defaultQueryProperties.setProperty("prepStmtCacheSqlLimit", "2048");
        defaultQueryProperties.setProperty("useLocalSessionState", Boolean.TRUE.toString());
        defaultQueryProperties.setProperty("rewriteBatchedStatements", Boolean.TRUE.toString());
        defaultQueryProperties.setProperty("cacheResultSetMetadata", Boolean.FALSE.toString());
        defaultQueryProperties.setProperty("cacheServerConfiguration", Boolean.TRUE.toString());
        defaultQueryProperties.setProperty("elideSetAutoCommits", Boolean.TRUE.toString());
        defaultQueryProperties.setProperty("maintainTimeStats", Boolean.FALSE.toString());
        defaultQueryProperties.setProperty("netTimeoutForStreamingResults", "0");
        defaultQueryProperties.setProperty("tinyInt1isBit", Boolean.FALSE.toString());
        defaultQueryProperties.setProperty("useSSL", Boolean.FALSE.toString());
        defaultQueryProperties.setProperty("serverTimezone", "UTC");
        defaultQueryProperties.setProperty("zeroDateTimeBehavior", "round");
    }
}

2.4 KingBaseOptimizerBuilder.java

java 复制代码
package org.apache.shardingsphere.infra.federation.optimizer.context.parser.dialect.impl;

import org.apache.calcite.config.CalciteConnectionProperty;
import org.apache.calcite.config.Lex;
import org.apache.calcite.sql.fun.SqlLibrary;
import org.apache.calcite.sql.validate.SqlConformanceEnum;
import org.apache.shardingsphere.infra.federation.optimizer.context.parser.dialect.OptimizerSQLDialectBuilder;
import java.util.Properties;

/**
 * Optimizer properties builder for KingBase.
 */
public class KingBaseOptimizerBuilder implements OptimizerSQLDialectBuilder {

    @Override
    public Properties build() {
        Properties result = new Properties();
        result.setProperty(CalciteConnectionProperty.LEX.camelName(), Lex.JAVA.name());
        result.setProperty(CalciteConnectionProperty.CONFORMANCE.camelName(), SqlConformanceEnum.BABEL.name());
        result.setProperty(CalciteConnectionProperty.FUN.camelName(), SqlLibrary.POSTGRESQL.fun);
        return result;
    }

    @Override
    public String getType() {
        return "kingbase8";
    }

    @Override
    public boolean isDefault() {
        return true;
    }
}

2.5 在META-INFO/services配置文件文件中添加配置,加载文件

2.6 修改ShardingSphereResultSet.java中的getIndexFromColumnLabelAndIndexMap()方法

java 复制代码
//解决分页count别名找不到问题
private Integer getIndexFromColumnLabelAndIndexMap(final String columnLabel) throws SQLFeatureNotSupportedException {
        Integer columnIndex;
        if("count".equalsIgnoreCase(columnLabel)){
             columnIndex = columnLabelAndIndexMap.get("count(0)");
        }else{
             columnIndex = columnLabelAndIndexMap.get(columnLabel);
        }
        if (null == columnIndex) {
            throw new SQLFeatureNotSupportedException(String.format("can't get index from columnLabel[%s].", columnLabel));
        }
        return columnIndex;
    }

2.7 打包说明

修改完文件之后,执行maven install打到本地仓库,应用服务引用修改过后的jar,就可以正常启动运行了

3. 源码编译问题总结

3.1 Caused by: com.kingbase8.util.KsQLExceptionat :

The _column name config_id was not found in this ResultSet

分析: 这是因为表名字与人大金仓默认表名字重叠,获取列元数据的时候,执行失败

解决方案:

  1. 指定获取元数据的数据库模式(比如直接写死public,推荐)

  2. 修改表名字

3.2 can't get index from columnLabel[count]

分析: 分页count别名找不到问题

解决方法:

  1. 参考2.6 (推荐)

  2. 修改分页插件,重写分页拦截器,指定别名 (不推荐)

相关推荐
一个诺诺前行的后端程序员4 小时前
springcloud微服务实战<1>
spring·spring cloud·微服务
IT毕设梦工厂4 小时前
计算机毕业设计选题推荐-在线拍卖系统-Java/Python项目实战
java·spring boot·python·django·毕业设计·源码·课程设计
是梦终空5 小时前
JAVA毕业设计176—基于Java+Springboot+vue3的交通旅游订票管理系统(源代码+数据库)
java·spring boot·vue·毕业设计·课程设计·源代码·交通订票
工业互联网专业6 小时前
毕业设计选题:基于springboot+vue+uniapp的驾校报名小程序
vue.js·spring boot·小程序·uni-app·毕业设计·源码·课程设计
无名指的等待7127 小时前
SpringBoot中使用ElasticSearch
java·spring boot·后端
.生产的驴7 小时前
SpringBoot 消息队列RabbitMQ 消费者确认机制 失败重试机制
java·spring boot·分布式·后端·rabbitmq·java-rabbitmq
AskHarries8 小时前
Spring Boot利用dag加速Spring beans初始化
java·spring boot·后端
苹果酱05678 小时前
一文读懂SpringCLoud
java·开发语言·spring boot·后端·中间件
掐指一算乀缺钱9 小时前
SpringBoot 数据库表结构文档生成
java·数据库·spring boot·后端·spring
一叶飘零_sweeeet9 小时前
为什么 Feign 要用 HTTP 而不是 RPC?
java·网络协议·http·spring cloud·rpc·feign