Qt连接MySQL按时间节点下载表中数据

一.执行数据库命令

CREATE DATABASE IF NOT EXISTS bak_db;    //创建一个名为bak_db的数据库
USE bak_db;

CREATE TABLE IF NOT EXISTS water (      //创建一个名为water的数据表
    id INT AUTO_INCREMENT PRIMARY KEY,
    data_value VARCHAR(255) NOT NULL,
    timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO write (data_value, timestamp) VALUES
('RandomValue1', NOW() - INTERVAL FLOOR(RAND() * 365) DAY),
('RandomValue2', NOW() - INTERVAL FLOOR(RAND() * 365) DAY),
('RandomValue3', NOW() - INTERVAL FLOOR(RAND() * 365) DAY),
// 加上其他17行以生成20个总条目
('RandomValue20', NOW() - INTERVAL FLOOR(RAND() * 365) DAY);

请注意,以上 SQL 代码需要在数据库管理工具或 SQL 客户端中执行。data_value 字段被设置成一个简单的字符串,你可以根据需要调整它。timestamp 字段自动生成当前时间,并随机减去最多365天,以模拟不同的时间点。

二.设计Qt程序

1.打开Qt Creator并创建一个新的项目,命名为project2

  编辑.pro文件

QT       += core gui sql
QT += widgets


greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = MeterReadingsDownloader
TEMPLATE = app

CONFIG += c++11

SOURCES += main.cpp \
           mainwindow.cpp \
           databasemanager.cpp

HEADERS += mainwindow.h \
           databasemanager.h

FORMS += mainwindow.ui

   2.创建DataManager类

创建一个datamanager.h头文件,定义DataManager类,这个类会处理数据库连接和数据抽取的逻辑:

#ifndef DATABASEMANAGER_H
#define DATABASEMANAGER_H

#include <QString>
#include <QSqlQuery>


class DatabaseManager {
public:
    DatabaseManager();
    void downloadData(const QString& fileName, const QString& dateOption);
};
#endif // DATABASEMANAGER_H

3.创建一个datamanager.cpp源文件,实现DataManager类的方法:

#include "databasemanager.h"
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QFile>
#include <QTextStream>
#include <QDebug>

DatabaseManager::DatabaseManager()
{
}

void DatabaseManager::downloadData(const QString& fileName, const QString& dateOption)
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setDatabaseName("your_database");     //数据库名
    db.setUserName("your_username");         //用户名
    db.setPassword("your_password");         //用户密码

    if (!db.open()) {
        qDebug() << "Database connection failed:" << db.lastError();
        return;
    }

    // Prepare the SQL query based on the dateOption
    QString queryStr;
    if (dateOption == "按天") {
        queryStr = "SELECT reading_date, SUM(reading) FROM meter_readings GROUP BY reading_date;";
    } else if (dateOption == "按月") {
        queryStr = "SELECT DATE_FORMAT(reading_date, '%Y-%m') AS month, SUM(reading) FROM meter_readings GROUP BY month;";
    } else if (dateOption == "按年") {
        queryStr = "SELECT YEAR(reading_date) AS year, SUM(reading) FROM meter_readings GROUP BY year;";
    }

    QSqlQuery query(queryStr, db);
    QFile file(fileName);

    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qDebug() << "Couldn't open file for writing.";
        db.close();
        return;
    }

    QTextStream out(&file);

    while (query.next()) {
        out << query.value(0).toString() << "," << query.value(1).toString() << "\n";
    }

    file.close();
    db.close();
}

4.编写main.cpp

#include "mainwindow.h"
#include <QApplication>
#include <QMainWindow>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();

}

5.创建UI界面

在 mainwindow.ui 使用 Qt Designer 来创建一个简单的界面,包括一个下拉菜单(QComboBox)和一个按钮(QPushButton)用于触发下载。

6.编写mainwindow.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_downloadButton_clicked();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

7.编写mainwindow.cpp文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "databasemanager.h"
#include <QFileDialog>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // Assume the comboBox and downloadButton have been set up in the UI designer with these object names
    connect(ui->downloadButton, &QPushButton::clicked, this, &MainWindow::on_downloadButton_clicked);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_downloadButton_clicked()
{
    QString dateOption = ui->comboBox->currentText();
    QString fileName = QFileDialog::getSaveFileName(this, tr("保存CSV文件"), "", tr("CSV文件 (*.csv)"));
    if (!fileName.isEmpty()) {
        DatabaseManager dbManager;
        dbManager.downloadData(fileName, dateOption);
    }
}

三.注意

  1. 数据库认证信息安全: 数据库的用户名和密码不应该硬编码在源代码中。应该使用配置文件、环境变量或者安全的加密存储方式来管理敏感信息。

  2. 错误处理: 数据库连接、SQL查询、文件操作等都有可能失败,因此需要有充分的错误处理机制,比如使用Qt的异常处理以及 QSqlQuery 的错误检查功能。

  3. SQL注入防范: 使用参数化查询或Qt的SQL绑定功能来防止SQL注入攻击。

  4. 资源管理: 注意资源管理,确保数据库连接和文件句柄在使用完毕后能够被正确释放。可以利用Qt的父子对象机制及智能指针来管理资源。

  5. 文件保存格式: 当创建CSV文件时,确保字段值中没有包含逗号或新行等可能引起格式混淆的字符。如果有,应该正确地转义这些值或用引号包围。

  6. 字符编码: 文件应按照一个统一的字符编码进行保存,例如UTF-8。这对于国际化很重要,特别是当内容包含非ASCII字符时。

  7. 文件路径和权限: 用户选择的文件保存路径需要有写入权限,且要处理路径不存在或文件无法创建等情况。

  8. Qt版本兼容性: 确保你使用的QT版本与你的代码兼容。如果你需要在不同的操作系统上部署,还要考虑跨平台的兼容性问题。

  9. 内存管理: 当使用Qt时,特别是在创建对象时,要注意父子关系,因为Qt使用的是父子层次结构来管理内存。

  10. 用户体验: 文件导出可能需要一些时间,特别是数据量大的时候。考虑使用异步编程或者单独的工作线程来处理长时间运行的任务,以避免阻塞UI线程。

  11. 数据类型匹配: 当处理数据库和CSV文件时,确保数据类型在转换过程中保持一致。

  12. 测试: 进行充分的单元测试和集成测试来确保应用程序按预期工作。

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值