Windows环境下Qt连接数据库的相关问题

一、了解ODBC

不同的数据库产品有不同的API接口,这使得程序开发变得繁琐。为了解决这一问题出现了ODBC。但是每种数据库产品需要准备各自的ODBC驱动程序。
一般地,当你安装了某种数据库产品就会自带相关地ODBC驱动。对于Qt程序而言,当计算机有了某种驱动程序,Qt才能操作相应数据库产品。

二、查看数据源

如何查看我们地Qt程序能够访问那些数据库?
在Windows里搜索“数据源”,点击“ODBC数据源”
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
在出现的弹框里选择“驱动程序”
在这里插入图片描述
如上图所示,我的Qt程序可以操作office的Access数据库、开源的MySQL数据库、微软的SQL Server数据库。

三、Qt访问数据库的基本步骤

  1. 添加SQL模块
    在这里插入图片描述

  2. 包含数据库操作相关头文件
    在这里插入图片描述

  3. 初始化数据库连接信息,连接数据库
    (这里以连接Access数据库为例)在这里插入图片描述

  4. 执行增删查改操作
    在这里插入图片描述

四、Qt程序连接数据库可能出现的问题

1.MinGW与MSVC
目前,在Windows环境下,如果使用MinGW编译器,则只能使用32位的ODBC驱动。这样大多数数据库会出现连接失败的情况,就是因为MinGW编译出的可执行程序只能使用32位ODBC驱动,而大多数数据库产品提供的是64位的ODBC驱动。
而当使用MSVC编译,则成功几率大大提高。如:在连接MySQL数据库时,使用QtCreator+MinGW编译,QSqlDatabase的实例对象在执行open()时总是返回“false”。
将同样的代码移入配好Qt环境的Visual Studio中编译即可返回“true”。因为Visual Studio可以生成64位可执行程序,也就可以访问64位的ODBC。

五、Qt操作Microsoft Access Database数据库类分装

头文件

#ifndef SQLITEMANAGER_H
#define SQLITEMANAGER_H

#include <QTextCodec>
#include <QSqlQuery>
#include <QTime>
#include <QtDebug>
#include <QByteArray>
#include <QVariantList>
#include <QDateTime>

#include <QSqlError>
#include <QSqlDriver>
#include <QSqlRecord>
#include <QSqlDatabase>

struct CustomData;
class SQLiteManager
{

public:
    SQLiteManager(int limitCount = 3);
    bool openDataBase();
    void createTable(QString tableName);
    void insertToTable(const QString &tableName);
    void queryResult(const QString &dealType, bool result, QSqlQuery query);
    QList<CustomData> selectData(const QString &tableName);
    void initDatabaseInfo(const QString &strFileName,
                          const QString &strUsrName = "",
                          const QString &strPasswd = "");
    QString getError();
    void setDifferValue(qint64 strDifferTime);
    bool timeCheckResult(const QDateTime &datetime);
    void openTimeCheck(bool isOpen);

private:
    QSqlDatabase    m_database;
    int             m_nLimitCount{3};
    QString         m_strError;
    bool            m_bTimeCheck{true};
    qint64          m_nMsecValue;
};

#endif // SQLITEMANAGER_H

源文件

#include "SQLiteManager.h"
#include <QApplication>
#include "datastruct.h"

#define MS_ACCESS_DATABASE ("DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};FIL={MS Access};")
SQLiteManager::SQLiteManager(int limitCount) : m_nLimitCount(limitCount)
{

}

// 打开数据库
bool SQLiteManager::openDataBase()
{
    if(m_database.open())
    {
        qDebug() << "数据库打开成功";
        return true;
    }
    else
    {
        qDebug() << m_database.lastError().text();
    }
    qDebug() << "--------------------------------------";
    return false;
}


// 创建数据库表(示例)
void SQLiteManager::createTable(QString tableName)
{
    QSqlQuery query;
    bool createTableResult =  query.exec(QString("create table %1(id int primary key, name varchar, age int)").arg(tableName));
    QString dealTypeStr = "创建表";
    queryResult(dealTypeStr, createTableResult, query);
}

//向表中插入数据(示例)
void SQLiteManager::insertToTable(const QString &tableName)
{
    QSqlQuery query;
    query.prepare(QString("insert into %1"
                          "(Num, UserID, PosTime, PosType, Coordinat, Longitude, Latitude, Altitude) "
                          "values(?, ?, ?, ?, ?, ?, ?, ?)").arg(tableName));

    QVariantList NumList;
    NumList << 523451 << 523452 << 523453 << 523454 << 523455 << 523456 << 523457 << 523458;
    QVariantList UserIDList;
    UserIDList << 856667 << 856668 << 856669 << 856670 << 856671 << 856672 << 856673 << 856674;

    QVariantList PosTimeList;
    PosTimeList << "2022/08/28 13:13:13"
                << "2022/08/28 13:13:13"
                << "2022/08/28 13:13:13"
                << "2022/08/28 13:13:13"
                << "2022/08/28 13:13:13"
                << "2022/08/28 13:13:13"
                << "2022/08/28 13:13:13"
                << "2022/08/28 13:13:13";

    QVariantList PosTypeList;
    PosTypeList << 18 << 19 << 20 << 18 << 19 << 20 << 18 << 19;
    QVariantList CoordinatList;
    CoordinatList << 18 << 19 << 20 << 18 << 19 << 20 << 18 << 19;

    QVariantList LongitudeList;
    LongitudeList << 81.435 << 81.435 << 81.435 << 81.435 << 81.435 << 81.435 << 81.435 << 81.435;
    QVariantList LatitudeList;
    LatitudeList << 81.435 << 81.435 << 81.435 << 81.435 << 81.435 << 81.435 << 81.435 << 81.435;
    QVariantList AltitudeList;
    AltitudeList << 81.435 << 81.435 << 81.435 << 81.435 << 81.435 << 81.435 << 81.435 << 81.435;

    query.addBindValue(NumList);
    query.addBindValue(UserIDList);
    query.addBindValue(PosTimeList);
    query.addBindValue(PosTypeList);
    query.addBindValue(CoordinatList);
    query.addBindValue(LongitudeList);
    query.addBindValue(LatitudeList);
    query.addBindValue(AltitudeList);


    bool insertTableResult = query.execBatch();
    QString dealTypeStr = "表插入";
    queryResult(dealTypeStr, insertTableResult, query);
}

//查询读取数据(示例)
QList<CustomData> SQLiteManager::selectData(const QString &tableName)
{
    QList<CustomData> selctResult;
    QSqlQuery query;
    bool selectResult = query.exec(QString(R"(SELECT TOP %1 * FROM %2 ORDER BY Num DESC;)").arg(m_nLimitCount).arg(tableName));
    if(selectResult)
    {
        CustomData oneData;
        while (query.next())
        {
            oneData.Num       = query.value(0).toInt();
            oneData.UserID    = query.value(1).toInt();
            oneData.PosTime   = query.value(2).toDateTime().toString("yyyy-MM-dd hh:mm:ss");
            oneData.PosType   = query.value(3).toInt();
            oneData.Coordinat = query.value(4).toInt();
            oneData.Longitude = query.value(5).toDouble();
            oneData.Latitude  = query.value(6).toDouble();
            oneData.Altitude  = query.value(7).toDouble();
            if(timeCheckResult(query.value(2).toDateTime()))
                selctResult.push_back(oneData);
        }
    }
    QString strOperateType = "查询";
    queryResult(strOperateType, selectResult, query);
    return selctResult;
}

void SQLiteManager::initDatabaseInfo(const QString &strFileName, const QString &strUsrName, const QString &strPasswd)
{
    QString strDBName = QString(MS_ACCESS_DATABASE + QString("DBQ=%1;").arg(strFileName));
    m_database = QSqlDatabase::addDatabase("QODBC");
    m_database.setDatabaseName(strDBName);
    m_database.setUserName(strUsrName);
    m_database.setPassword(strPasswd);
}

//SQL执行结果
void SQLiteManager::queryResult(const QString &dealType, bool result, QSqlQuery query)
{
    if(result)
    {
        qDebug() << QString("%1成功").arg(dealType);
    }
    else
    {
        qDebug() << QString("%1失败").arg(dealType) << query.lastError().text();
        m_strError = QString("%1失败").arg(dealType) + query.lastError().text();
    }
    qDebug() << "--------------------------------------";

}

QString SQLiteManager::getError()
{
    return m_strError;
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆呆的菜菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值