Qt连接数据库的两种方法

我曾经想过,无论在哪个平台下开发,都不要再接触SQL Server了,但显然不行。我们是来看世界的,不是来改变世界的,想通就好。

前两天,尝试了一下Qt下远程访问数据库。在macOS下,用Qt 5.11写个程序来远程访问Win10下的SQL Server和My SQL数据库,Qt中通过QSqlDatabase来创建一个数据库连接。简单来说,QSqlDatabase连接数据库可以分为两种方式,聊到这两种方式,就要大概的说一下数据访问的前因后果,以微软的数据访问历史为例,本文只是从快速使用的角度出发,不会讲得太详细深入。

一、 数据访问方式的历史

在早期时,由于数据库种类繁多,各种数据库连接有不同的需求,数据库连接主要依靠各种API函数来进行连接,数据库编程都是直接操作数据库厂商提供的API,每个数据库厂商的提供的数据库操作的API都不相同,如调用函数,操作语句等等。因此每个应用程序都只能对应一个数据库。如果想换数据库,需要重写一遍数据库操作代码,这样的代价是非常大的。因此Microsoft就联合一些厂家做了个接口标准——ODBC。

ODBC(Open Database Connectivity,开放数据库互连)

1992年Microsoft和Sybase、Digital共同制定了ODBC 接口标准,以标准的ODBC API来存取各种不同的数据库。ODBC将所有数据库特定的,底层的操作细节(CLI)封装在驱动(drive)中,并提供一套标准的函数调用。使用时,ODBC会动态地加载数据库的CLI,将函数调用转换成各个数据库的CLI调用。这样应用程序与数据库API本身就隔绝开了,ODBC本身也提供了对SQL语言的支持,用户可以直接将SQL语句送给ODBC,如下图所示。

这样访问所有的关系型数据库都可以使用一套标准的ODBC API即可。ODBC成为最早的通用数据库访问技术。随后ODBC便获得了许多数据库厂商和Third-Party的支持而逐渐成为标准的数据存取技术。

ODBC以当时的业界标准规范X/OpenCall-LevelInterface(CLI)和ISO/IEC9075-3Call-LevelInterface(SQL/CLI)为涵盖的范围,因而支持了广阔的数据库。虽然ODBC在初期的版本中执行效率不佳,而且功能有限,因此也为人们所贬低。但是,随着Microsoft不断地改善ODBC,使ODBC的执行效率不断增加,ODBC驱动程序的功能也日渐齐全。到目前,ODBC已经是一个稳定并且执行效率良好的数据存取引擎。

OLE DB(Object Linking and Embedding DataBase,对象链接和嵌入数据库)

ODBC是最早的通用数据访问技术,但是ODBC只限于检索关系型数据库的数据。

1997年, Microsoft 的一个战略性系统级编程接口,用于管理整个组织内的数据。OLE DB 是建立在 ODBC 功能之上的一个开放规范。ODBC 是为访问关系型数据库而专门开发的,OLE DB 则用于访问关系型和非关系型信息源,例如主机 ISAM/VSAM 和层次数据库,电子邮件和文件系统存储,文本、图形和地理数据以及自定义业务对象。

在OLE DB中,不再有drive的概念,取而代之的是提供者(provider),每个数据库厂商都需要对象的OLE DB provider。需要注意的是,provider实现了基于COM的接口,这些接口封装了访问数据库的操作细节(CLI)。那么应用程序使用这些通用的接口来进行数据库的访问,而不用考虑数据库的细节。所以,可以理解OLE DB是规定了数据使用者和提供者之间达成了一种协议。
为了兼容一些没有提供provider的数据库,OLE DB也可以基于ODBC,即provider是基于ODBC实现的。这种实现会经过两层,效率会比较低。由于目前大多数数据库都提供了provider,所以这种方式比较少见。 可以看到,OLE DB与ODBC类似,但是原理上是不相同的。如下图:

ADO(ActiveX Data Object,ActiveX数据对象)

微软为了简化OLE DB接口,推出了ADO来封装OLE DB的接口,实现与数据库的通信,使得用户更易于调用数据库相关操作。ADO实际上是位于OLE DB顶部的一个附加层(也就是位于OLE DB与应用程序之间),它封装了OLE DB。

ADO被设计来继承微软早期的数据访问对象层,包括RDO(Remote DataObjects)和DAO(Data Access Objects)。随着.NET推出,微软进一步进行升级ADO为ADO.NET。

二、Qt选程访问数据

本开发环境在macOS平台下,用Qt 5.11开发程序来远程访问Win10下的数据库。使用Parallesl安装一个Win10 虚拟机,IP地址为10.211.55.4,在Win10中安装了Visual Studio Community 2017、SQL Server 2008 Express、MySQL Community 8.0.14。

在Qt中,QSqlDatabase类提供一个通过数据库连接来访问数据库的接口。一个QSqlDatabase的实例代表了一个数据库连接。数据库连接通过数据库驱动提供对数据库的访问,数据库驱动继承自QSqlDriver。

QSqlDatabase 当前支持的驱动类型如下:

基于ODBC连接数据库

准备工作1:安装odbc manager, 不装第二步会报错
下载地址: http://www.odbcmanager.net/
准备工作2:安装mysql odbc connector
下载地址: https://dev.mysql.com/downloads/connector/odbc/
开始编码。
首先,在Qt的工程文件中加入:

QT       += sql

在源代码文件中引用以下头文件,其中QPluginLoader、QDebug是为了调试用的:

#include <QSqlDatabase>
#include <QSqlError>
#include <QPluginLoader>
#include <QDebug>

先写个loadPlugin函数来检测Qt 有没编译好的ODBC驱动,在 /Users/Hula/Qt/5.11.2/clang_64/plugins/sqldrivers/libqsqlodbc.dylib 对应填上你自己的Qt安装文件路径,代码如下:

void HDbm::loadPlugin()
{
    QPluginLoader loader;
    // ODBC 驱动插件的路径
    loader.setFileName("/Users/Hula/Qt/5.11.2/clang_64/plugins/sqldrivers/libqsqlodbc.dylib");
    qDebug() << loader.load();
    qDebug() << loader.errorString();
}

简单的写个数据库连接函数:

int HDbm::createSQLServerConnection()
{
    loadPlugin();

    QString strHost = "10.211.55.4";
    int port = 3306;
    QString strDbName = "SQLData";
    QString strUserName = "test";
    QString strUserPwd = "123321";
    QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
    QString strconn = QString("Driver={sql server};SERVER=%1;PORT=%2;DATABASE=%3;UID=%4;PWD=%5;")
                          .arg(strHost)
                          .arg(port)
                          .arg(strDbName)
                          .arg(strUserName)
                          .arg(strUserPwd);
    db.setDatabaseName(strconn);
    if (!db.open())
    {
        qDebug() <<"error_SqlServer:" << db.lastError().text();
        return 1201;
    }

    return 0;
}

调用createSQLServerConnection函数即可。
如果出现以下错误:

The shared library was not found.
QSqlDatabase: QODBC driver not loaded ((null):0, (null))

表示Qt没有 libqsqlodbc 驱动,需要自己动手编译Qt的源码,具体方法自动上网搜索。

使用Qt的QSqlDriver 数据库驱动连接数据库

首先安装MySQL Connector/C,MySQL官网上没有此安装文件,有两种方法来完成,一是用 brew 安装 MySQL,brew 将 MySQL 安装在 usr?/?local?/?lib/mysql 目录下,由于Qt 调用 ?usr?/?local?/?lib? 下的 MySQL 驱动,因此将 usr?/?local?/?lib/mysql 目录下的驱动文件 libmysqlclient.dylib 链接到 usr?/?local?/?lib 目录下即可。

或从 https://dev.mysql.com/downloads/mysql/ 下载MySQL Community Server的压缩包,解压后,拷贝 lib 目录中文件到 usr?/?local?/?lib 下即可。

同上,MySQL数据库连接函数:

int HDbm::createMySQLConnection()
{
    loadPlugin();

    QString strHost = "10.211.55.4";
    int port = 3306;
    QString strDbName = "SQLData";
    QString strUserName = "test";
    QString strUserPwd = "123321";
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    // 防止连接超时无反应,设置连接超时3秒
    db.setConnectOptions("MYSQL_OPT_CONNECT_TIMEOUT=3");
    db.setHostName(strHost);
    db.setPort(port);
    db.setDatabaseName(strDbName);
    db.setUserName(strUserName);
    db.setPassword(strUserPwd);
    if (!db.open())
    {
        qDebug() <<"error_SqlServer:" << db.lastError().text();
        return 1201;
    }

    return 0;
}
三、补充说明

在Qt的文档中对QSqlDatabase这个类的描述如下:

The QSqlDatabase class handles a connection to a database.
The QSqlDatabase class provides an interface for accessing a database through a connection. An instance of QSqlDatabase represents the connection. The connection provides access to the database via one of the supported database drivers, which are derived from QSqlDriver. Alternatively, you can subclass your own database driver from QSqlDriver. See How to Write Your Own Database Driver for more information.

如果你使用的数据库不在上表Qt当前支持的驱动类型中,你可以从QSqlDriver类构建你自己的数据库驱动。有两种方法,一是找到数据库厂商的 for ODBC dirver,如果没有,也可以通过数据库厂商的 for C/C++ dirver 自己封装一个 for ODBC dirver,通过 ODBC 访问数据库;再就是从QSqlDriver类构建一个的数据库驱动,来调用数据库厂商的 for C dirver,更为方便简单。

另,ODBC不同数据库连接字符串:

access
"Driver={microsoft access driver(*.mdb)};dbq=*.mdb;uid=admin;pwd=pass;"

dBase
 "Driver={microsoft dbase driver(*.dbf)};driverid=277;dbq=***;"

oracle
"Driver={microsoft odbc for oracle};server=oraclesever.world;uid=admin;pwd=pass;"

MSSQL server
"Driver={sql server};server=servername;database=dbname;uid=sa;pwd=pass;"

MS text
"Driver={microsoft text driver(*.txt; *.csv)};dbq=**;extensions=asc,csv,tab,txt;Persist SecurityInfo=false;"

Visual Foxpro
 "Driver={microsoft Visual Foxpro driver};sourcetype=DBC;sourceDB=*.dbc;Exclusive=No;"

MySQL
"Driver={mysql};database=yourdatabase;uid=username;pwd=yourpassword;option=16386;"

SQLite
"Driver={SQLite3 ODBC Driver};Database=D:\SQLite\*.db"

PostgreSQL
"Driver={PostgreSQL ANSI};server=127.0.0.1;uid=admin;pwd=pass;database=databaseName"

原文地址:https://www.cnblogs.com/ihula/p/10545634.html

时间: 2024-08-07 23:12:25

Qt连接数据库的两种方法的相关文章

QT中获取选中的radioButton的两种方法(动态取得控件的objectName之后,对名字进行比较)

QT中获取选中的radioButton的两种方法 QT中要获取radioButton组中被选中的那个按钮,可以采用两种如下两种办法进行: 方法一:采用对象名称进行获取 代码: 1 QRadioButton* pbtn = qobject_cast<QRadioButton*>(ui->BG->checkedButton()); 2 QString name = pbtn->objectName(); 3 if(!QString::compare(name, "rad

Qt 之 设置窗口边框的圆角(使用QSS和PaintEvent两种方法)

Qt在设置窗口边框圆角时有两种方式,一种是设置样式,另一种是在paintEvent事件中绘制窗口.下面分别叙述用这两种方式来实现窗口边框圆角的效果. 一.使用setStyleSheet方法 this->setStyleSheet(“QWidget{border-top-left-radius:15px;border-top-right-radius:5px;}”)); 使用的主要是使用border-radius 属性,关于这个属性,可选的样式有 border-top-left-radius 设置

QT中获取选中的radioButton的两种方法

QT中要获取radioButton组中被选中的那个按钮,可以采用两种如下两种办法进行: 方法一:采用对象名称进行获取 代码: 1 QRadioButton* pbtn = qobject_cast<QRadioButton*>(ui->BG->checkedButton()); 2 QString name = pbtn->objectName(); 3 if(!QString::compare(name, "radioButton")) 4 { 5 QM

SQL Server 批量插入数据的两种方法

在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Insert不仅效率低,而且会导致SQL一系统性能问题.下面介绍SQL Server支持的两种批量数据插入方法:Bulk和表值参数(Table-Valued Parameters). 运行下面的脚本,建立测试数据库和表值参数. [c-sharp] view plaincopy --Create DataBase create database BulkTestDB; go use BulkTes

C++连接mysql数据库的两种方法

现在正做一个接口,通过不同的连接字符串操作不同的数据库.要用到mysql数据库,以前没用过这个数据库,用access和sql server比较多.通过网上的一些资料和自己的摸索,大致清楚了C++连接mysql的方法.可以通过2种方法实现. 第一种方法是利用ADO连接, 第二种方法是利用mysql自己的api函数进行连接. 第一种方法可以实现我当前的需求,通过连接不同的字符串来连接不同的数据库.暂时只连接了mysql,sqlserver,oracle,access.对于access,因为它创建表的

DataGridView显示数据的两种方法

1.简单介绍 DataGridView空间是我们常用的显示数据的控件,它有极高的可配置性和可扩展性. 2.显示数据 DataGridView显示数据一般我们常用的有两种方法,一种是直接设置DataSoure属性就可以绑定数据.此方法不需要写任何代码操作比较简单,但是它显示出来的是整张表的数据.如果整一表数据比较多,而且我们并不需要所有的数据的情况下,我们就应该考虑第二种方法了.通过写代码连接数据库并从数据库中读取数据,最后将返回的数据传给DataGridView.这种方法貌似比较复杂,但是它只显

在下拉列表中显示多个字段的两种方法

首先,我们需要从数据库中取到我们的数据 Class1: 1 string sqlcon = "Data Source=.;Initial Catalog=Test;User ID=sa;Password=******"; 2 3 public List<ModelClass> FindAll() 4 { 5 try 6 { 7 List<ModelClass> modList = new List<ModelClass>(); 8 using (Sq

[MongoDB学习笔记-02] Node.js连接MongoDB的两种方法

MongoDB Node.js驱动程序是被官方所支持的原生Node.js驱动程序,他是至今为止最好的实现, 并且得到了MongoDB官方的支持.MongoDB团队已经采用MongoDB Node.js驱动程序作为标准方法. npm install mongodb@1.4.3 // MongoDB Node.js驱动程序 npm install mongoose@3.8.8 //mongoose模块 要从Node.js连接MongoDB数据库我们有两种方法可选择: 通过实例化mongodb模块中提

在linux环境下编译运行OpenCV程序的两种方法

原来以为在Ubuntu下安装好了OpenCV之后,自己写个简单的程序应该很容易吧,但是呢,就是为了编译一个简单的显示图片的程序我都快被弄崩溃了. 在谷歌和上StackOverFlow查看相关问题解答之后,我下面就介绍Command Line和CMake两种方式. 首先我先粘上我测试的代码吧,文件名为Test.c 1 #include <highgui.h> 2 3 int main(int argc,char ** argv) { 4 5 IplImage* img = cvLoadImage