MySQL环境项目迁移成国产化达梦环境

1、数据迁移

1.1、达梦数据库及工具安装:

a、达梦版本如下,产品下载 - 武汉达梦数据库股份有限公司

b、工具

SQLark V3.8.1,官网:SQLark-信创数据库开发,用百灵

1.2、先进行达梦数据库配置:

复制代码
ALTER SYSTEM SET 'COMPATIBLE_MODE' = 4 SPFILE; //改mysql兼容模式

ALTER SYSTEM SET 'EXCLUDE_RESERVED_WORDS' = 'domain,verify,reference,offset,ref,type,login,admin' SPFILE; //关键字修改

1.2、再迁移:

使用里面的迁移功能,把mysql数据全量迁移到达梦中,连接达梦的时候使用SYSDBA,迁移过程会自动创建用户(同模式名,后续在java项目中使用),非常简单。

按上图一步步往下走就行

同步完成后再修改一下新建成的用户密码。

2、项目改造

2.1 引入maven依赖:
复制代码
     <dependency>
                <groupId>com.dameng</groupId>
                <artifactId>DmJdbcDriver8</artifactId>
                <version>8.1.4.93</version>
      </dependency>
2.2 在META-INF中加入SPI:(注意这里的services是子文件夹)

文件中的实现类为:

|--------------------------------------------------------------------------------------------------------------|----------------------------------------------------------|
| 文件名 | 值 |
| org.apache.shardingsphere.infra.database.type.DatabaseType | com.entry.customize.dmadapter.DMDatabaseType |
| org.apache.shardingsphere.sqlfederation.optimizer. context.parser.dialect.OptimizerSQLDialectBuilder | com.entry.customize.dmadapter.DMOptimizerBuilder |

DMOptimizerBuilder:

复制代码
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.sqlfederation.optimizer.context.parser.dialect.OptimizerSQLDialectBuilder;

import java.util.Properties;

 
public final class DMOptimizerBuilder implements OptimizerSQLDialectBuilder {

    @Override
    public Properties build() {
        Properties result = new Properties();
        result.setProperty(CalciteConnectionProperty.LEX.camelName(), Lex.MYSQL.name());
        result.setProperty(CalciteConnectionProperty.CONFORMANCE.camelName(), SqlConformanceEnum.MYSQL_5.name());
        result.setProperty(CalciteConnectionProperty.FUN.camelName(), SqlLibrary.MYSQL.fun);
        result.setProperty(CalciteConnectionProperty.CASE_SENSITIVE.camelName(), String.valueOf(Lex.MYSQL.caseSensitive));
        return result;
    }

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

    @Override
    public boolean isDefault() {
        return true;
    }
}
复制代码
DMDatabaseType:
复制代码
import org.apache.shardingsphere.infra.database.type.BranchDatabaseType;
import org.apache.shardingsphere.infra.database.type.DatabaseType;
import org.apache.shardingsphere.infra.database.type.DatabaseTypeFactory;
import org.apache.shardingsphere.sql.parser.sql.common.constant.QuoteCharacter;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;
 
public final class DMDatabaseType implements BranchDatabaseType {

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

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

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

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

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

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

    /**
     * //作为MySQL的子集,sql解析等操作使用MySQL的实现
     */
    @Override
    public DatabaseType getTrunkDatabaseType() {
        return DatabaseTypeFactory.getInstance("MySQL");
    }

核心元数据类

复制代码
DMDataSourceMetaData
复制代码
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;


@Getter
public final class DMDataSourceMetaData implements DataSourceMetaData {

    private static final int DEFAULT_PORT = 5236;

    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 DMDataSourceMetaData(final String url, final String username) {
        System.out.println("url--------"+url + "***********userName--------"+username);
        JdbcUrl jdbcUrl = new StandardJdbcUrlParser().parse(url);
        hostName = jdbcUrl.getHostname();
        port = -1 == jdbcUrl.getPort() ? DEFAULT_PORT : jdbcUrl.getPort();
        catalog = jdbcUrl.getDatabase();
        schema = username;
        queryProperties = jdbcUrl.getQueryProperties();
        buildDefaultQueryProperties();
    }

    @Override
    public String getHostname() {
        return this.hostName;
    }

    @Override
    public String getSchema() {
        return this.schema;
    }

    @Override
    public Properties getQueryProperties() {
        return this.queryProperties;
    }

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

    private void buildDefaultQueryProperties() {
        defaultQueryProperties.setProperty("useServerPrepStmts", Boolean.TRUE.toString());
        defaultQueryProperties.setProperty("cachePrepStmts", Boolean.TRUE.toString());
        defaultQueryProperties.setProperty("prepStmtCacheSize", "8192");
        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");
    }
}

YML配置:

XML 复制代码
spring:
  datasource:
    # 动态数据源配置
    dynamic:
      datasource:
        master:
          type: com.zaxxer.hikari.HikariDataSource
          driver-class-name: dm.jdbc.driver.DmDriver
          url: jdbc:dm://127.0.0.1:5238
          username: MYSQL  //当前用户会默认寻找对应的名称的模式名
          password: 123456
      primary: master

其他注意点:

a、关键字处理,一些达梦本身的特殊关键字如果在项目中出现了需要改一下;

b、复杂SQL改造,比如包含函数的SQL处;

c、注意大小写敏感问题;

d、分页场景还是使用MYSQL模式不变

相关推荐
@insist12324 分钟前
数据库系统工程师-Armstrong 公理系统:函数依赖推理与候选码求解核心方法论(重点)
数据库·软考·软件设计师·软件水平考试
山峰哥1 小时前
查询优化案例:从慢查询到闪电般的查询速度
数据库·sql·性能优化·编辑器·深度优先
杨云龙UP1 小时前
Oracle ASM磁盘组空间分配与冗余理解
linux·运维·数据库·sql·oracle
微学AI2 小时前
一款数据库SQL防火墙:可以拦截99.99%,可以阻止恶意SQL
数据库·sql
2401_884563242 小时前
Python Lambda(匿名函数):简洁之道
jvm·数据库·python
haixingtianxinghai3 小时前
Redis真的是单线程吗?
数据库·redis·缓存
FirstFrost --sy3 小时前
MySQL复合查询
数据库·mysql
imuliuliang3 小时前
MySQL的底层原理与架构
数据库·mysql·架构
尽兴-3 小时前
Redis7 底层数据结构解析
数据结构·数据库·缓存·redis7
m0_730115113 小时前
自动化机器学习(AutoML)库TPOT使用指南
jvm·数据库·python