本文主要记录了在飞腾架构麒麟V10系统下开发Qt应用程序时,如何通过ODBC连接达梦数据库,将ODBC的两个配置文件作为应用程序配置文件的一部分随程序打包发布,并在程序中动态设置ODBC需要的环境变量。
下载地址 https://www.unixodbc.org/download.html
解压 gunzip unixODBC*.tar.gz 或 tar xvf unixODBC*.tar
打开终端,cd到unixODBC源码所在目录下,执行编译安装命令:
./configure
make
make install
默认安装路径为/usr/local ,当然了也可以通过./configure --prefix=/usr/local/unixODBC
来指定安装目录。默认安装完成如下图所示。
首先添加两个环境变量,用终端打开.profile 文件,在最后增加两行
export ODBCINI=/usr/local/etc/odbc.ini
export ODBCSYSINI=/usr/local/etc
在终端执行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
[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
然后打开终端,将达梦数据库的odbc驱动和odbc动态库所在路径添加到LD_LIBRARY_PATH环境变量中,如果没有安装达梦数据库驱动,可以参考这篇文章来安装 飞腾架构麒麟V10安装达梦数据库客户端。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/dm/dmdbms/drivers/odbc:/usr/local/lib
设置好环境变量后,下面测试连接达梦数据库,cd到/usr/local/bin目录下,执行下面的命令,如果显示如下图所示的信息则表示连接成功。
isql -v MAIN
这里使用之前搭建麒麟开发环境时的Qt源码及编译好的qmake来编译QODBC,在麒麟V10环境下编译Qt,可以参考这篇文章,博客链接。qodbc在源码中的目录为 qt5.12.7/qtbase/src/plugins/sqldrivers/odbc
将原来的include 一行用#注释,改为下图红框中第二行所示的代码,因为qtsqldrivers-config.pri 文件中把odbc的编译设置为disable了
可以使用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
新建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
在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();
}
运行程序,通过观察打印日志,可以看到已经成功连接到达梦数据库,并查询到了数据。
为了程序部署时不用在每台电脑安装ODBC环境,现对ODBC的配置进行优化。先删除之前添加到.profile文件中的环境变量ODBCINI、ODBCSYSINI,以免影响测试结果。
DESTDIR = $$PWD/bin
然后在bin目录下新建lib目录,将ODBC的动态库及达梦的odbc驱动都复制到lib目录下
在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();
}
经过上面的调整之后,要想成功连接数据库,需要将bin/lib目录添加到LD_LIBRARY_PATH 变量中,以便程序能正确找到驱动所在位置。设置好环境变量再次运行程序,就能正常连接达梦数据库了。
这里使用linuxdeployqt进行打包,使用默认命令打包不会将/bin/lib目录下的odbc相关动态库拷贝到程序包的lib目录下的,这里需要手动拷贝bin/config 和 /bin/lib文件到程序包目录下。这时可以双击程序图标运行程序。如何在飞腾PC麒麟V10系统下安装使用linuxdeployqt打包工具可以参考这篇文章linuxdeployqt打包参考
以上就是本文的所有内容了,对本文内容有疑问的朋友欢迎留言讨论!可在此处下载本文demo源码连接。