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 columnLabelcount

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

解决方法:

  1. 参考2.6 (推荐)

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

相关推荐
IT_Octopus1 小时前
Spring Boot 线程池关闭:destroyMethod 的作用与最佳实践
java·spring boot·后端
霸道流氓气质3 小时前
SpringBoot中事务内同步处理 + 事务后异步调用外部系统的通用模式示例
java·spring boot·后端
Arya_aa5 小时前
jdk动态代理和AOP面向切面编程
spring boot
Full Stack Developme5 小时前
SpringBoot 整合 Druid 并列出参数清单
java·spring boot·后端
一知半解仙6 小时前
从0到1!Spring Cloud微服务无缝集成AI智能体:架构设计+核心源码+生产落地全指南
人工智能·spring cloud·微服务
January丶7 小时前
SpringBoot整合ElasticSearch
spring boot
前端双越老师7 小时前
Nest.js 和 Spring Boot 为何如此像?写给前端转 Java 的同学
java·spring boot·全栈
音符犹如代码7 小时前
Arthas classloader + sc 实战:JVM 类加载与手动加载
java·jvm·spring boot
Listen·Rain8 小时前
用AI开发出一个AI
java·人工智能·spring boot·tomcat·intellij-idea·mybatis·visual studio
马优晨11 小时前
Spring Boot + MyBatis + Redis 整合实战 —— 项目源码深度解析
spring boot·redis·mybatis·mybatis + redis·redis实战·spring实战·mybatis实战