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. 修改分页插件,重写分页拦截器,指定别名 (不推荐)

相关推荐
William一直在路上10 分钟前
SpringBoot 拦截器和过滤器的区别
hive·spring boot·后端
小马爱打代码1 小时前
Spring Boot 3.4 :@Fallback 注解 - 让微服务容错更简单
spring boot·后端·微服务
旷世奇才李先生1 小时前
奇哥面试记:SpringBoot整合RabbitMQ与高级特性,一不小心吊打面试官
spring boot·面试·java-rabbitmq
经典19922 小时前
spring boot 详解以及原理
java·spring boot·后端
白仑色3 小时前
Spring Boot 多环境配置详解
java·spring boot·后端·微服务架构·配置管理
超级小忍3 小时前
在 Spring Boot 中优化长轮询(Long Polling)连接频繁建立销毁问题
java·spring boot·后端
Z_W_H_4 小时前
【springboot】IDEA手动创建SpringBoot简单工程(无插件)
java·spring boot·intellij-idea
荔枝hu5 小时前
springboot生成pdf方案之dot/html/图片转pdf三种方式
spring boot·pdf·html
Z_W_H_8 小时前
【SpringBoot】 整合MyBatis+Postgresql
java·spring boot·后端
麦兜*9 小时前
【SpringBoot 】Spring Boot OAuth2 六大安全隐患深度分析报告,包含渗透测试复现、漏洞原理、风险等级及完整修复方案
java·jvm·spring boot·后端·spring·系统架构