欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

QT操作PostgreSQL數(shù)據(jù)庫并實(shí)現(xiàn)增刪改查功能

 更新時(shí)間:2025年05月15日 08:58:08   作者:code_shenbing  
Qt 提供了強(qiáng)大的數(shù)據(jù)庫支持,通過 Qt SQL 模塊可以方便地操作 PostgreSQL 數(shù)據(jù)庫,本文將詳細(xì)介紹如何在 Qt 中連接 PostgreSQL 數(shù)據(jù)庫,并實(shí)現(xiàn)基本的增刪改查(CRUD)操作,需要的朋友可以參考下

一、環(huán)境準(zhǔn)備

1. 安裝 PostgreSQL

確保已安裝 PostgreSQL 并創(chuàng)建了測試數(shù)據(jù)庫。

2. 安裝 Qt 開發(fā)環(huán)境

確保已安裝 Qt 開發(fā)環(huán)境(Qt Creator 或命令行工具)。

3. 配置 Qt 連接 PostgreSQL

在項(xiàng)目文件(.pro)中添加:

QT += sql

二、連接 PostgreSQL 數(shù)據(jù)庫

1. 基本連接方式

#include <QCoreApplication>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
#include <QDebug>
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    // 創(chuàng)建數(shù)據(jù)庫連接
    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
    
    // 設(shè)置連接參數(shù)
    db.setHostName("localhost");      // 主機(jī)名
    db.setPort(5432);                 // 端口
    db.setDatabaseName("testdb");     // 數(shù)據(jù)庫名
    db.setUserName("postgres");       // 用戶名
    db.setPassword("password");       // 密碼
    
    // 打開連接
    if (!db.open()) {
        qDebug() << "數(shù)據(jù)庫連接失敗:" << db.lastError().text();
        return -1;
    }
    
    qDebug() << "成功連接到數(shù)據(jù)庫";
    
    // 關(guān)閉連接
    db.close();
    
    return a.exec();
}

2. 使用連接池(推薦)

// 創(chuàng)建連接池
QSqlDatabase createConnectionPool(const QString &connectionName) {
    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL", connectionName);
    db.setHostName("localhost");
    db.setPort(5432);
    db.setDatabaseName("testdb");
    db.setUserName("postgres");
    db.setPassword("password");
    
    if (!db.open()) {
        qCritical() << "創(chuàng)建連接池失敗:" << db.lastError().text();
        return QSqlDatabase();
    }
    
    return db;
}
 
// 獲取連接
QSqlDatabase getConnection(const QString &connectionName) {
    QSqlDatabase db = QSqlDatabase::database(connectionName);
    if (!db.isOpen()) {
        if (!db.open()) {
            qCritical() << "獲取連接失敗:" << db.lastError().text();
            return QSqlDatabase();
        }
    }
    return db;
}
 
// 釋放連接
void releaseConnection(const QString &connectionName) {
    QSqlDatabase::removeDatabase(connectionName);
}

三、實(shí)現(xiàn)增刪改查操作

1. 創(chuàng)建測試表

首先在 PostgreSQL 中創(chuàng)建測試表:

CREATE TABLE employees (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    position VARCHAR(50),
    salary NUMERIC(10, 2),
    hire_date DATE
);

2. 插入數(shù)據(jù)(Add)

bool insertEmployee(QSqlDatabase &db, const QString &name, 
                    const QString &position, double salary, 
                    const QDate &hireDate) {
    QSqlQuery query(db);
    
    // 使用預(yù)處理語句防止SQL注入
    query.prepare("INSERT INTO employees (name, position, salary, hire_date) "
                  "VALUES (:name, :position, :salary, :hire_date)");
    
    query.bindValue(":name", name);
    query.bindValue(":position", position);
    query.bindValue(":salary", salary);
    query.bindValue(":hire_date", hireDate);
    
    if (!query.exec()) {
        qDebug() << "插入數(shù)據(jù)失敗:" << query.lastError().text();
        return false;
    }
    
    return true;
}

3. 查詢數(shù)據(jù)(Query)

3.1 查詢單條記錄

QSqlRecord getEmployeeById(QSqlDatabase &db, int id) {
    QSqlQuery query(db);
    query.prepare("SELECT * FROM employees WHERE id = :id");
    query.bindValue(":id", id);
    
    if (!query.exec() || !query.next()) {
        qDebug() << "查詢員工失敗:" << query.lastError().text();
        return QSqlRecord();
    }
    
    return query.record();
}

3.2 查詢所有記錄

QList<QSqlRecord> getAllEmployees(QSqlDatabase &db) {
    QList<QSqlRecord> employees;
    QSqlQuery query(db);
    query.exec("SELECT * FROM employees ORDER BY id");
    
    while (query.next()) {
        employees.append(query.record());
    }
    
    return employees;
}

3.3 使用模型查詢(Qt SQL 模型)

QSqlTableModel *createEmployeeModel(QObject *parent = nullptr) {
    QSqlTableModel *model = new QSqlTableModel(parent);
    model->setTable("employees");
    model->select();
    
    // 設(shè)置表頭
    model->setHeaderData(1, Qt::Horizontal, tr("Name"));
    model->setHeaderData(2, Qt::Horizontal, tr("Position"));
    model->setHeaderData(3, Qt::Horizontal, tr("Salary"));
    model->setHeaderData(4, Qt::Horizontal, tr("Hire Date"));
    
    return model;
}

4. 更新數(shù)據(jù)(Update)

bool updateEmployee(QSqlDatabase &db, int id, 
                    const QString &name, const QString &position, 
                    double salary, const QDate &hireDate) {
    QSqlQuery query(db);
    query.prepare("UPDATE employees SET name = :name, position = :position, "
                  "salary = :salary, hire_date = :hire_date WHERE id = :id");
    
    query.bindValue(":name", name);
    query.bindValue(":position", position);
    query.bindValue(":salary", salary);
    query.bindValue(":hire_date", hireDate);
    query.bindValue(":id", id);
    
    if (!query.exec()) {
        qDebug() << "更新員工失敗:" << query.lastError().text();
        return false;
    }
    
    return true;
}

5. 刪除數(shù)據(jù)(Delete)

bool deleteEmployee(QSqlDatabase &db, int id) {
    QSqlQuery query(db);
    query.prepare("DELETE FROM employees WHERE id = :id");
    query.bindValue(":id", id);
    
    if (!query.exec()) {
        qDebug() << "刪除員工失敗:" << query.lastError().text();
        return false;
    }
    
    return true;
}

四、完整示例

1. 使用控制臺(tái)程序演示CRUD操作

#include <QCoreApplication>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtSql/QSqlError>
#include <QtSql/QSqlRecord>
#include <QDebug>
#include <QDate>
 
bool openDatabase(QSqlDatabase &db) {
    db = QSqlDatabase::addDatabase("QPSQL");
    db.setHostName("localhost");
    db.setPort(5432);
    db.setDatabaseName("testdb");
    db.setUserName("postgres");
    db.setPassword("password");
    
    if (!db.open()) {
        qDebug() << "數(shù)據(jù)庫連接失敗:" << db.lastError().text();
        return false;
    }
    return true;
}
 
void closeDatabase(QSqlDatabase &db) {
    db.close();
}
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    QSqlDatabase db;
    if (!openDatabase(db)) {
        return -1;
    }
    
    // 插入數(shù)據(jù)
    QSqlQuery query(db);
    query.prepare("INSERT INTO employees (name, position, salary, hire_date) "
                  "VALUES (:name, :position, :salary, :hire_date)");
    
    query.bindValue(":name", "張三");
    query.bindValue(":position", "開發(fā)工程師");
    query.bindValue(":salary", 15000.00);
    query.bindValue(":hire_date", QDate::currentDate());
    
    if (!query.exec()) {
        qDebug() << "插入失敗:" << query.lastError().text();
    } else {
        qDebug() << "插入成功,ID:" << query.lastInsertId().toInt();
    }
    
    // 查詢數(shù)據(jù)
    QSqlQuery selectQuery(db);
    selectQuery.exec("SELECT * FROM employees ORDER BY id");
    
    while (selectQuery.next()) {
        QSqlRecord record = selectQuery.record();
        qDebug() << "ID:" << record.value("id").toInt()
                 << "姓名:" << record.value("name").toString()
                 << "職位:" << record.value("position").toString()
                 << "薪資:" << record.value("salary").toDouble()
                 << "入職日期:" << record.value("hire_date").toDate();
    }
    
    // 更新數(shù)據(jù)
    query.prepare("UPDATE employees SET salary = :salary WHERE id = :id");
    query.bindValue(":salary", 16000.00);
    query.bindValue(":id", 1); // 假設(shè)ID為1的員工
    
    if (!query.exec()) {
        qDebug() << "更新失敗:" << query.lastError().text();
    } else {
        qDebug() << "更新成功";
    }
    
    // 刪除數(shù)據(jù)
    query.prepare("DELETE FROM employees WHERE id = :id");
    query.bindValue(":id", 1); // 假設(shè)要?jiǎng)h除ID為1的員工
    
    if (!query.exec()) {
        qDebug() << "刪除失敗:" << query.lastError().text();
    } else {
        qDebug() << "刪除成功";
    }
    
    closeDatabase(db);
    return a.exec();
}

2. 使用Qt Widgets實(shí)現(xiàn)GUI界面

// employeeform.h
#ifndef EMPLOYEEFORM_H
#define EMPLOYEEFORM_H
 
#include <QWidget>
#include <QSqlTableModel>
#include <QDataWidgetMapper>
 
QT_BEGIN_NAMESPACE
namespace Ui { class EmployeeForm; }
QT_END_NAMESPACE
 
class EmployeeForm : public QWidget
{
    Q_OBJECT
 
public:
    EmployeeForm(QWidget *parent = nullptr);
    ~EmployeeForm();
 
private slots:
    void on_addButton_clicked();
    void on_saveButton_clicked();
    void on_deleteButton_clicked();
    void on_refreshButton_clicked();
 
private:
    Ui::EmployeeForm *ui;
    QSqlTableModel *model;
    QDataWidgetMapper *mapper;
};
 
#endif // EMPLOYEEFORM_H
 
// employeeform.cpp
#include "employeeform.h"
#include "ui_employeeform.h"
#include <QSqlDatabase>
#include <QSqlError>
#include <QMessageBox>
 
EmployeeForm::EmployeeForm(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::EmployeeForm)
{
    ui->setupUi(this);
 
    // 連接數(shù)據(jù)庫
    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
    db.setHostName("localhost");
    db.setPort(5432);
    db.setDatabaseName("testdb");
    db.setUserName("postgres");
    db.setPassword("password");
 
    if (!db.open()) {
        QMessageBox::critical(this, "錯(cuò)誤", "無法連接到數(shù)據(jù)庫: " + db.lastError().text());
        return;
    }
 
    // 創(chuàng)建模型
    model = new QSqlTableModel(this, db);
    model->setTable("employees");
    model->select();
 
    // 設(shè)置表頭
    model->setHeaderData(1, Qt::Horizontal, tr("姓名"));
    model->setHeaderData(2, Qt::Horizontal, tr("職位"));
    model->setHeaderData(3, Qt::Horizontal, tr("薪資"));
    model->setHeaderData(4, Qt::Horizontal, tr("入職日期"));
 
    // 設(shè)置視圖
    ui->tableView->setModel(model);
    ui->tableView->setEditTriggers(QAbstractItemView::DoubleClicked);
 
    // 設(shè)置數(shù)據(jù)映射器
    mapper = new QDataWidgetMapper(this);
    mapper->setModel(model);
    mapper->addMapping(ui->nameEdit, 1);
    mapper->addMapping(ui->positionEdit, 2);
    mapper->addMapping(ui->salaryEdit, 3);
    mapper->addMapping(ui->hireDateEdit, 4);
 
    // 連接信號(hào)槽
    connect(ui->tableView->selectionModel(), &QItemSelectionModel::currentRowChanged,
            this, [this](const QModelIndex &current, const QModelIndex &) {
                mapper->setCurrentModelIndex(current);
            });
}
 
EmployeeForm::~EmployeeForm()
{
    delete ui;
}
 
void EmployeeForm::on_addButton_clicked()
{
    int row = model->rowCount();
    model->insertRow(row);
    ui->tableView->selectRow(row);
    mapper->setCurrentIndex(row);
    ui->nameEdit->setFocus();
}
 
void EmployeeForm::on_saveButton_clicked()
{
    if (!model->submitAll()) {
        QMessageBox::warning(this, "錯(cuò)誤", "保存失敗: " + model->lastError().text());
    } else {
        model->database().transaction();
        if (model->submitAll()) {
            model->database().commit();
            QMessageBox::information(this, "成功", "數(shù)據(jù)保存成功");
        } else {
            model->database().rollback();
            QMessageBox::warning(this, "錯(cuò)誤", "保存失敗: " + model->lastError().text());
        }
    }
}
 
void EmployeeForm::on_deleteButton_clicked()
{
    QModelIndex index = ui->tableView->currentIndex();
    if (index.isValid()) {
        int ret = QMessageBox::question(this, "確認(rèn)", "確定要?jiǎng)h除這條記錄嗎?",
                                        QMessageBox::Yes | QMessageBox::No);
        if (ret == QMessageBox::Yes) {
            model->removeRow(index.row());
            if (!model->submitAll()) {
                QMessageBox::warning(this, "錯(cuò)誤", "刪除失敗: " + model->lastError().text());
                model->revertAll();
            }
        }
    }
}
 
void EmployeeForm::on_refreshButton_clicked()
{
    model->select();
}

五、高級(jí)功能

1. 事務(wù)處理

bool performTransaction(QSqlDatabase &db) {
    db.transaction();
    
    QSqlQuery query(db);
    bool success = true;
    
    // 執(zhí)行多個(gè)操作
    if (!query.exec("INSERT INTO employees (...) VALUES (...)" )) {
        success = false;
    }
    
    if (!query.exec("UPDATE ...")) {
        success = false;
    }
    
    if (success) {
        db.commit();
    } else {
        db.rollback();
    }
    
    return success;
}

2. 批量插入

bool batchInsertEmployees(QSqlDatabase &db, const QList<QVariantList> &employees) {
    QSqlDatabase::database().transaction();
    
    QSqlQuery query(db);
    query.prepare("INSERT INTO employees (name, position, salary, hire_date) "
                  "VALUES (?, ?, ?, ?)");
    
    foreach (const QVariantList &employee, employees) {
        query.addBindValue(employee);
        if (!query.execBatch()) {
            QSqlDatabase::database().rollback();
            return false;
        }
    }
    
    QSqlDatabase::database().commit();
    return true;
}

3. 使用存儲(chǔ)過程

bool callStoredProcedure(QSqlDatabase &db, int employeeId) {
    QSqlQuery query(db);
    query.prepare("CALL update_employee_salary(:id, :percentage)");
    query.bindValue(":id", employeeId);
    query.bindValue(":percentage", 10); // 增加10%
    
    if (!query.exec()) {
        qDebug() << "調(diào)用存儲(chǔ)過程失敗:" << query.lastError().text();
        return false;
    }
    
    return true;
}

六、常見問題解決

1. 連接失敗

  • 檢查PostgreSQL服務(wù)是否運(yùn)行
  • 驗(yàn)證連接參數(shù)(主機(jī)名、端口、數(shù)據(jù)庫名、用戶名、密碼)
  • 檢查防火墻設(shè)置
  • 確保安裝了PostgreSQL客戶端庫

2. 中文亂碼

// 設(shè)置編碼
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));

或者在連接字符串中指定編碼:

db.setConnectOptions("client_encoding=UTF8");

3. 性能優(yōu)化

  • 使用預(yù)處理語句
  • 批量操作代替單條操作
  • 合理使用事務(wù)
  • 為常用查詢創(chuàng)建索引

七、總結(jié)

Qt 提供了強(qiáng)大而靈活的數(shù)據(jù)庫訪問功能,通過 Qt SQL 模塊可以輕松實(shí)現(xiàn) PostgreSQL 數(shù)據(jù)庫的增刪改查操作。本文介紹了從基本連接到高級(jí)功能的實(shí)現(xiàn)方法,并提供了完整的代碼示例。在實(shí)際開發(fā)中,可以根據(jù)項(xiàng)目需求選擇合適的實(shí)現(xiàn)方式,結(jié)合事務(wù)處理、批量操作等技術(shù)提高應(yīng)用性能。

以上就是QT操作PostgreSQL數(shù)據(jù)庫并實(shí)現(xiàn)增刪改查功能的詳細(xì)內(nèi)容,更多關(guān)于QT操作PostgreSQL增刪改查的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 基于PostgreSQL/openGauss?的分布式數(shù)據(jù)庫解決方案

    基于PostgreSQL/openGauss?的分布式數(shù)據(jù)庫解決方案

    ShardingSphere-Proxy?作為透明數(shù)據(jù)庫代理,用戶無需關(guān)心?Proxy?如何協(xié)調(diào)背后的數(shù)據(jù)庫。今天通過本文給大家介紹基于PostgreSQL/openGauss?的分布式數(shù)據(jù)庫解決方案,感興趣的朋友跟隨小編一起看看吧
    2021-12-12
  • postgresql如何查詢重復(fù)計(jì)數(shù)及去重查詢

    postgresql如何查詢重復(fù)計(jì)數(shù)及去重查詢

    這篇文章主要介紹了postgresql如何查詢重復(fù)計(jì)數(shù)及去重查詢問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • sqoop 實(shí)現(xiàn)將postgresql表導(dǎo)入hive表

    sqoop 實(shí)現(xiàn)將postgresql表導(dǎo)入hive表

    這篇文章主要介紹了sqoop 實(shí)現(xiàn)將postgresql表導(dǎo)入hive表,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • PostgreSQL 正則表達(dá)式替換-使用變量方式

    PostgreSQL 正則表達(dá)式替換-使用變量方式

    這篇文章主要介紹了PostgreSQL 正則表達(dá)式替換-使用變量方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • PostgreSQL中date_trunc函數(shù)的語法及一些示例

    PostgreSQL中date_trunc函數(shù)的語法及一些示例

    這篇文章主要給大家介紹了關(guān)于PostgreSQL中date_trunc函數(shù)的語法及一些示例的相關(guān)資料,DATE_TRUNC函數(shù)是PostgreSQL數(shù)據(jù)庫中用于截?cái)嗳掌诓糠值暮瘮?shù),文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-04-04
  • PostgreSQL教程(二十):PL/pgSQL過程語言

    PostgreSQL教程(二十):PL/pgSQL過程語言

    這篇文章主要介紹了PostgreSQL教程(二十):PL/pgSQL過程語言,本文講解了、PL/pgSQL概述、PL/pgSQL的結(jié)構(gòu)、聲明、基本語句、控制結(jié)構(gòu)等內(nèi)容,需要的朋友可以參考下
    2015-05-05
  • PostgreSQL標(biāo)準(zhǔn)建表語句分享

    PostgreSQL標(biāo)準(zhǔn)建表語句分享

    這篇文章主要介紹了PostgreSQL標(biāo)準(zhǔn)建表語句分享,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • springboot 沒法掃描到repository的解決

    springboot 沒法掃描到repository的解決

    這篇文章主要介紹了springboot 沒法掃描到repository的解決,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • postgresql修改自增序列操作

    postgresql修改自增序列操作

    這篇文章主要介紹了postgresql修改自增序列操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Postgresql根據(jù)響應(yīng)數(shù)據(jù)反向?qū)崿F(xiàn)建表語句與insert語句的過程

    Postgresql根據(jù)響應(yīng)數(shù)據(jù)反向?qū)崿F(xiàn)建表語句與insert語句的過程

    根據(jù)已有數(shù)據(jù),可構(gòu)建名為products的表,包含id(自增主鍵)、title(非空字符串)、progress(非空整數(shù))三個(gè)字段,建表后,可通過insert語句插入數(shù)據(jù),這種反向操作有助于從現(xiàn)有數(shù)據(jù)結(jié)構(gòu)出發(fā),快速構(gòu)建數(shù)據(jù)庫表,并進(jìn)行數(shù)據(jù)填充,感興趣的朋友跟隨小編一起看看吧
    2022-02-02

最新評論