Windows环境Qt连接数据库相关问题
- 一、了解ODBC
- 二、查看数据源
- 三、Qt访问数据库的基本步骤
- 四、Qt程序连接数据库可能出现的问题
- 五、Qt操作Microsoft Access Database数据库类分装
一、了解ODBC
不同的数据库产品有不同的API接口,这使得程序开发变得繁琐。为了解决这一问题出现了ODBC。但是每种数据库产品需要准备各自的ODBC驱动程序。
一般地,当你安装了某种数据库产品就会自带相关地ODBC驱动。对于Qt程序而言,当计算机有了某种驱动程序,Qt才能操作相应数据库产品。
二、查看数据源
如何查看我们地Qt程序能够访问那些数据库?
在Windows里搜索“数据源”,点击“ODBC数据源”
在出现的弹框里选择“驱动程序”
如上图所示,我的Qt程序可以操作office的Access数据库、开源的MySQL数据库、微软的SQL Server数据库。
三、Qt访问数据库的基本步骤
- 添加SQL模块
- 包含数据库操作相关头文件
- 初始化数据库连接信息,连接数据库
(这里以连接Access数据库为例) - 执行增删查改操作
四、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;
}