• Qt应用程序连接达梦数据库-飞腾PC麒麟V10


    前言

    本文主要记录了在飞腾架构麒麟V10系统下开发Qt应用程序时,如何通过ODBC连接达梦数据库,将ODBC的两个配置文件作为应用程序配置文件的一部分随程序打包发布,并在程序中动态设置ODBC需要的环境变量。

    1 安装ODBC

    1.1 下载unixODBC源码

    下载地址 https://www.unixodbc.org/download.html
    解压 gunzip unixODBC*.tar.gz 或 tar xvf unixODBC*.tar

    1.2 编译安装

    打开终端,cd到unixODBC源码所在目录下,执行编译安装命令:

    ./configure
    make
    make install
    
    • 1
    • 2
    • 3

    默认安装路径为/usr/local ,当然了也可以通过./configure --prefix=/usr/local/unixODBC 来指定安装目录。默认安装完成如下图所示。
    在这里插入图片描述

    1.4 测试

    首先添加两个环境变量,用终端打开.profile 文件,在最后增加两行

    export ODBCINI=/usr/local/etc/odbc.ini
    export ODBCSYSINI=/usr/local/etc
    
    • 1
    • 2

    在终端执行source .profile命令使环境变量生效,飞腾PC麒麟V10需要重启生效。

    修改odbc.ini文件,配置达梦数据库信息

    [MAIN]
    Description=DM ODBC DSN
    Driver=MAIN ODBC DRIVER
    SERVER=192.168.1.2
    UID=SYSDBA
    PWD=123456789
    TCP_PORT=5236
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    [MAIN]
    Driver=<驱动程序名称,与odbcinst.ini文件中[MAIN ODBC DRIVER]名称对应>
    SERVER=<数据库服务器地址>
    UID=<数据库用户名>
    PWD=<数据库用户密码>
    TCP_PORT=<数据库服务器端口>

    修改odbcinst.ini,配置达梦驱动

    [MAIN ODBC DRIVER]
    Description=ODBC DRIVER FOR MAIN
    Driver=/dm/dmdbms/drivers/odbc/libdodbc.so
    
    • 1
    • 2
    • 3

    然后打开终端,将达梦数据库的odbc驱动和odbc动态库所在路径添加到LD_LIBRARY_PATH环境变量中,如果没有安装达梦数据库驱动,可以参考这篇文章来安装 飞腾架构麒麟V10安装达梦数据库客户端

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/dm/dmdbms/drivers/odbc:/usr/local/lib
    
    • 1

    设置好环境变量后,下面测试连接达梦数据库,cd到/usr/local/bin目录下,执行下面的命令,如果显示如下图所示的信息则表示连接成功。

    isql -v MAIN 
    
    • 1

    在这里插入图片描述

    2 编译QODBC

    这里使用之前搭建麒麟开发环境时的Qt源码及编译好的qmake来编译QODBC,在麒麟V10环境下编译Qt,可以参考这篇文章,博客链接。qodbc在源码中的目录为 qt5.12.7/qtbase/src/plugins/sqldrivers/odbc

    2.1 修改 qsqldriverbase.pri 文件

    将原来的include 一行用#注释,改为下图红框中第二行所示的代码,因为qtsqldrivers-config.pri 文件中把odbc的编译设置为disable了
    在这里插入图片描述

    2.2 修改 odbc.pro 文件

    把QMAKE_USE一行用#注释掉
    在这里插入图片描述

    2.3 编译并安装QODBC

    可以使用QtCreator,也可以直接用命令编译,这里演示用命令编译QODBC。从 1.2 节知道unixODBC安装在/usr/local 目录下,编译qodbc需要用到unixODBC的头文件和动态库。在qodbc源码目录下打开终端,执行下面的命令后可生成libqsqlodbc.so库,并安装到qt安装目录的plugins/sqldrviers目录下。

    ../../../../bin/qmake "INCLUDEPATH+=/usr/local/include" "LIBS+=-L/usr/local/lib -lodbc" odbc.pro
    
    make
    make install
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    3 Qt应用程序连接达梦数据库测试

    新建Qt工程,pro文件如下

    QT       += core gui sql network
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    CONFIG += c++11
    DEFINES += QT_DEPRECATED_WARNINGS
    SOURCES += \
        main.cpp \
        mainwindow.cpp
    HEADERS += \
        mainwindow.h
    FORMS += \
        mainwindow.ui
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在mainwindow.cpp中添加测试代码

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include 
    #include 
    #include 
    #include 
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        qDebug() << QSqlDatabase::drivers();
    
        QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
        db.setHostName("192.168.1.2");
        db.setPort(5236);
    
        QString dsn=QString::fromLocal8Bit("DRIVER={MAIN ODBC DRIVER};SERVER=192.168.1.2;DATABASE=MAIN");
    
        db.setDatabaseName(dsn);
        //db.setDatabaseName("MAIN");   //这里数据库名要设置成上面odbc.ini配置文件中的MAIN,即表空间名
        db.setUserName("SYSDBA");
        db.setPassword("123456789");
        if (db.open())
        {
            qDebug() << "connect ok!";
        }
        else
        {
            qDebug() << "connect fail! " << db.lastError().text();
        }
    
        QSqlQuery query;
        QString strsql = "select name from Category";
        if (query.exec(strsql))
        {
            qDebug() << "select ok!";
        }
        else
        {
            qDebug() << "select fail! " << query.lastError().text();
        }
        while (query.next())
        {
            qDebug() << query.value(0).toString();
        }
        query.clear();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    运行程序,通过观察打印日志,可以看到已经成功连接到达梦数据库,并查询到了数据。

    4 优化ODBC配置,方便程序部署

    为了程序部署时不用在每台电脑安装ODBC环境,现对ODBC的配置进行优化。先删除之前添加到.profile文件中的环境变量ODBCINI、ODBCSYSINI,以免影响测试结果。

    4.1 修改pro文件,增加DESTDIR 变量配置
    DESTDIR = $$PWD/bin
    
    • 1
    4.2 新建lib目录,拷贝驱动到工程目录下

    然后在bin目录下新建lib目录,将ODBC的动态库及达梦的odbc驱动都复制到lib目录下
    在这里插入图片描述

    4.3 增加config目录,存放ODBC配置文件

    在bin目录下新建config目录,并将odbc.ini 和 odbcinst.ini复制到config目录下,因为odbcinst.ini文件中指定了ODBC驱动的绝对路径,因此要在程序中动态修改odbcinst.ini文件内容。下面的代码演示了在main.cpp中动态设置环境变量 ODBCINI、ODBCSYSINI。

    #include "mainwindow.h"
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    void envConfig(const QString &appPath)
    {
        //设置ODBC环境变量
    #ifdef linux
        //这里的设置都是打包后路径的设置
        QString odbcdriver = "libdodbc.so";
    
        QString odbcIni = appPath + "/config/odbc.ini";
        QString odbcsysini = appPath + "/config";
        QString librarypath = appPath + "/lib";
    
        //重新设置ODBC驱动路径
        QString odbcInstIni = appPath + "/config/odbcinst.ini";
        QFile odbcinstFile(odbcInstIni);
        if(odbcinstFile.open(QIODevice::ReadOnly))
        {
            QByteArray byteArr = odbcinstFile.readAll();
            int index = byteArr.indexOf("Driver") + sizeof ("Driver");
            int len = byteArr.size() - index;
            byteArr.replace(index, len, odbcdriver.prepend(librarypath + "/").toLocal8Bit().data());
    
            odbcinstFile.close();
            if(odbcinstFile.open(QIODevice::WriteOnly))
            {
                odbcinstFile.write(byteArr);
                odbcinstFile.close();
            }
        }
    
        //settings.setValue("ZODA ODBC DRIVER/Driver", odbcdriver.prepend(librarypath + "/"));
    
        //设置ODBC环境变量
        setenv("ODBCINI", odbcIni.toLocal8Bit().data(), 0);
        setenv("ODBCSYSINI", odbcsysini.toLocal8Bit().data(), 0);
    #endif
    }
    
    int main(int argc, char *argv[])
    {
        QString appFilePath = QString(argv[0]);
        QFileInfo appFileInfo(appFilePath);
        qDebug() <<  appFileInfo.absolutePath();
        envConfig(appFileInfo.absolutePath());
    
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    4.3 设置LD_LIBRARY_PATH 环境变量

    经过上面的调整之后,要想成功连接数据库,需要将bin/lib目录添加到LD_LIBRARY_PATH 变量中,以便程序能正确找到驱动所在位置。设置好环境变量再次运行程序,就能正常连接达梦数据库了。
    在这里插入图片描述

    4.4 打包部署

    这里使用linuxdeployqt进行打包,使用默认命令打包不会将/bin/lib目录下的odbc相关动态库拷贝到程序包的lib目录下的,这里需要手动拷贝bin/config 和 /bin/lib文件到程序包目录下。这时可以双击程序图标运行程序。如何在飞腾PC麒麟V10系统下安装使用linuxdeployqt打包工具可以参考这篇文章linuxdeployqt打包参考

    总结

    以上就是本文的所有内容了,对本文内容有疑问的朋友欢迎留言讨论!可在此处下载本文demo源码连接

  • 相关阅读:
    预编译为什么能防止SQL注入?一看你就明白了。预编译原理详解
    力扣labuladong——一刷day32
    编辑照片时,出现闪退
    Ubuntu使用linux-wifi-hotspot创建WIFI热点
    Pytorch-工业应用中如何选取合适的损失函数(MAE、MSE、Huber)
    【毕业设计】17-基于单片机的矿井提升机_步进电机控制装置设计(原理图+仿真+源代码+实物图+答辩论文+答辩PPT)
    【C++11】std::function 包装器(又叫适配器),std::bind 绑定
    Coredump-Z: map 释放后再使用的问题;多线程
    态路小课堂丨InfiniBand AOC有源光缆简介
    提升个人认知的六个学习方法
  • 原文地址:https://blog.csdn.net/zheng19880607/article/details/132747482