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

相关推荐
村口张大爷1 天前
Spring Boot 初始化钩子
java·spring boot·后端
LB21121 天前
苍穹外卖-缓存套餐 Spring Cache day07
java·spring boot·spring
W.Buffer1 天前
SpringCloud-Sentinel实战与源码分析:从流量防护到底层实现
spring·spring cloud·sentinel
Q_Q5110082851 天前
python+uniapp基于微信小程序的学院设备报修系统
spring boot·python·微信小程序·django·flask·uni-app
小毛驴8501 天前
在Spring Boot开发中,HEAD、OPTIONS和 TRACE这些HTTP方法各有其特定的应用场景和实现方式
spring boot·后端·http
Jabes.yang1 天前
Java面试大作战:从缓存技术到音视频场景的探讨
java·spring boot·redis·缓存·kafka·spring security·oauth2
zl9798991 天前
SpringBoot-依赖管理和自动配置
spring boot·后端·状态模式
paopaokaka_luck1 天前
基于SpringBoot+Vue的数码交流管理系统(AI问答、协同过滤算法、websocket实时聊天、Echarts图形化分析)
vue.js·人工智能·spring boot·websocket·echarts
Seven971 天前
Springboot 常见面试题汇总
java·spring boot
洛克大航海1 天前
1-springcloud-支付微服务准备
java·spring cloud·微服务