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模式不变

相关推荐
北凉军2 小时前
java连接达梦数据库,用户名是其他库的名称无法指定库,所有mapper查询的都是以用户名相同的库内的表
java·开发语言·数据库
尽兴-2 小时前
MySQL索引优化:从理论到实战
数据库·mysql·优化·b+树·索引·最左前缀
ZKNOW甄知科技2 小时前
IT自动分派单据:让企业服务流程更智能、更高效的关键技术
大数据·运维·数据库·人工智能·低代码·自动化
小光学长3 小时前
基于Web的长江游轮公共服务系统j225o57w(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库
Davina_yu3 小时前
2026年节假日表SQL
数据库·sql
是娇娇公主~3 小时前
工厂模式详细讲解
数据库·c++
天码-行空4 小时前
Linux 系统 MySQL 8.0 详细安装教程
linux·运维·mysql
码农小卡拉4 小时前
数据库:主键 VS 唯一索引 区别详解
java·数据库·sql
廋到被风吹走4 小时前
【数据库】【MySQL】锁机制深度解析:从原理到死锁分析实战
数据库·mysql