一、前言

最近项目中需要使用达梦数据库,之前项目的架构是SpringBoot+Mybatis+MySQL,要改为SpringBoot+Mybatis+DM的,简而言之就是把数据库换成国产的达梦数据库。

二、环境准备

我用的是window版的DM8,可以到达梦官网下载不同版本[下载地址]
达梦服务端
从官网下载后安装即可,需要注意的是达梦需要进行初始化,初始化中有几个参数:
CASE_SENSITIVE:这个是设置达梦是否区分大小写的,1是区分大小写,0是不区分大小写,这个酌情选择
LENGTH_IN_CHAR:长度是否以字符为单位,0是以字节为单位,1是以字符为单位,如果选0的话则会按照字节来,而MySQL5.x中的长度是以字符为单位的,就可能会出现在达梦中字段长度不够的情况;
UNICODE_FLAG:使用什么字符集,0是unicode,1是utf-8,这个看情况选择,一般都是用的utf-8。
如果不注意,后面就会出现达梦字段的长度不够的情况,当然建表时手动乘上字符所占的字节数也可以,这个可以通过达梦的管理工具查看:在连接上右键->管理服务器->系统概览,如图
请添加图片描述
达梦连接工具
达梦连接工具的话,其实可以直接用达梦自己的连接工具,也可以用Debeaver
但是Debeaver需要单独进行配置,配置流程可以百度,需要的驱动包在达梦安装目录的drivers/jdbc下面,根据达梦版本选择即可。
达梦语法
具体的语法可以参考达梦的官方文档,这里就简单的列举一下我遇到的与MySQL的不同之处:

  • 创建表时int,tinyint不能指定长度
  • 自增列的写法为IDENTITY(1, 1)
  • 没有longblob,达梦的blob长度最大为2G-1字节的数据。
  • 没有反引号,用双引号,这里达梦跟Oracle语法有点像,用双引号来转义标识符,用单引号表示字符串
  • 达梦的case when的结果不能是一个表达式,只能是具体的结果,即最终的返回,比如select (case when 1=1 then 1=1 else 0=1 end)会报错select (case when 1=1 then 1 else 0 end)这样才可以,在实际使用中可能需要看情况修改sql语句
  • 达梦没有find_in_set函数,如果用的话需要自建,可以参考这篇文章:https://blog.51cto.com/xiaok007/2139728
  • 查询字段元数据语句不同,达梦没有show full fields from %s这种的语句,我找到的一个办法是进行多表联查,下面是我自己拼的一个sql,如果有什么更方便的方法,可以评论一下,大家共同进步
select
    *
from
        user_tab_columns t1
left join user_ind_columns uic
on
        t1.table_name  = uic.table_name
    and t1.column_name = uic.column_name
left join user_constraints uc
on
        uic.index_name = uc.index_name
left join SYSCOLUMNCOMMENTS t2
on
        t2.TVNAME  = t1.table_name
    and t2.COLNAME = t1.column_name
where
        t1.table_name = '%s';

达梦连接驱动
达梦的连接驱动就是在达梦安装目录的drivers/jdbc下面,根据达梦版本选择即可。
我选的是DmJdbcDriver18.jar
配置里的DriverClass写dm.jdbc.driver.DmDriver

三、项目应用

数据迁移(已有项目的改造)
我们是对已有项目的改造所以会涉及到数据迁移的问题,如果是新的项目可以跳过这步。
数据迁移推荐用达梦自带的迁移工具,如果用sql脚本导出导入的形式会有许多语法问题,不推荐。
数据迁移达梦提供了数据迁移工具,在安装目录的tool目录下的dts
1、打开软件
2、在迁移管理窗口内右键,新建工程(如果没有迁移管理窗口,可以点击视图->窗口->迁移管理打开)
3、输入工程名、描述,确定,这里的工程名是便于我们区分的名字
请添加图片描述
4、点击展开新建的工程,在迁移上右键->新建迁移请添加图片描述
5、输入迁移名称、描述,确定,这里也是便于我们区分的迁移名称
6、点击确定后进入首页,直接下一步
7、然后选择要迁移的数据,也支持从达梦导出到其他数据库,我这里是MySQL迁移到达梦,选择后下一步
请添加图片描述
8、进行MySQL数据源的配置,选择要迁移的数据库,配置完成后下一步,如果MySQL版本不是5.x的推荐手动指定驱动
请添加图片描述
9、配置达梦的数据源,下一步请添加图片描述
10、在框内打勾,然后可以选择目的模式,就是要导入的库名,创建模式可以勾选上,如果没有的话会新建,下一步请添加图片描述
11、选择要迁移的表,可以点击选择全选,下一步
请添加图片描述
12、这里就是看一下任务的执行情况,没有什么问题点击完成即可进行数据迁移,如果存在任务报错的情况,可以手动处理,比如建表失败,可以复制建表语句修改后手动在达梦数据库中执行,然后尝试重新迁移,将数据导入。
依赖
我们项目用的是Maven,引入依赖的话需要先将驱动包上传到私服上,然后Maven引入
如果是Eclipse的话可以直接添加jar包
Gradle的话也可以使用手动指定jar包的方式,或者上传私服也可以
这里就放一下Maven依赖的写法做个参考

<dependency>
     <groupId>com.dm</groupId>
     <artifactId>dmjdbc8</artifactId>
     <version>1.8.0</version>
</dependency>

Mybatis方式
如果使用的是Mybatis的方式,改动一下配置文件即可。这里把比较关键的几个配置贴一下

spring:
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: dm.jdbc.driver.DmDriver
        druid:
            master:
                url: jdbc:dm://localhost:5236/TEST
                username: username
                password: password

JDBC方式
JDBC方式也可以访问,代码如下

  static final String JDBC_DRIVER = "dm.jdbc.driver.DmDriver";
  static final String DB_URL = "jdbc:dm://localhost:5236";
  
  static final String USER = "username";
  static final String PASS = "password";

  public static void main(String[] args) {
    Connection conn = null;
    PreparedStatement stmt = null;
    try {
      // 注册 JDBC 驱动
      Class.forName(JDBC_DRIVER);
      // 打开链接
      System.out.println("连接数据库...");
      conn = DriverManager.getConnection(DB_URL, USER, PASS);
      // 执行查询
      System.out.println(" 实例化Statement对象...");
      stmt = conn.prepareStatement("select * from TEST.test1");
      ResultSet rs = stmt.executeQuery();
      // 展开结果集数据库
      while (rs.next()) {
        // 通过字段检索
        int id = rs.getInt(1);
        // 输出数据
        System.out.println("ID: " + id);
      }
      // 完成后关闭
      rs.close();
      stmt.close();
      conn.close();
    } catch (SQLException se) {
      se.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      // 关闭资源
      try {
        if (stmt != null) {
          stmt.close();
        }
      } catch (SQLException se2) {
      }
      try {
        if (conn != null) {
          conn.close();
        }
      } catch (SQLException se) {
        se.printStackTrace();
      }
    }
  }

四、常见问题及解决方案

达梦主要的问题在于不能通过链接指定数据库,所以如果连接的数据库与用户默认的数据库不一致需要单独在语句中指定。
如果出现上述情况,最简单的就是直接改语句,如果语句无法改动,则可以尝试修改配置文件,比如指定数据库名,或者在表前缀前面加上数据库名,如果没有配置,则需要修改源码了
兼容Mybatis
这里也是说的如果连接的数据库与用户默认的数据库不一致的话,需要在语句中指定数据库名以数据库名.表名的形式来写Sql
兼容Activiti
这个可以参考https://blog.csdn.net/qq_42046342/article/details/105148196,如果是Maven建议直接覆盖私服jar包,然后清理本地jar包后重新打包
如果报无效的表名或者视图名,则是查询默认的表名没有找到,如果是上面我说的数据库不一致的问题,需要新建ActivitiConfig配置类,如果有了,就在configure方法下面新增三行代码。

@Override
    public void configure(SpringProcessEngineConfiguration processEngineConfiguration) {
        processEngineConfiguration.setActivityFontName("宋体");
        processEngineConfiguration.setAnnotationFontName("宋体");
        processEngineConfiguration.setLabelFontName("宋体");
        processEngineConfiguration.setProcessDiagramGenerator(customProcessDiagramGenerator);
        // 加入以下代码, 指定数据库表前缀,加上 库名.
        processEngineConfiguration.setDatabaseTablePrefix("database.");
        processEngineConfiguration.setTablePrefixIsSchema(true);
        processEngineConfiguration.setDatabaseSchemaUpdate("no");
    }

兼容Quartz
Quartz其实也是数据库名与用户默认的名称不同步的问题,可以在Quartz的配置类中的表名前缀中加入数据库名.即可

"org.quartz.jobStore.tablePrefix", "database.QRTZ_"

五、后记

这次使用达梦我也是一知半解,各种百度拼起来的,如果文中那里有误,欢迎指出,大家共同交流进步!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐