最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

1. 安裝 PostgreSQL

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

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

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

3. 配置 Qt 連接 PostgreSQL

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

QT += sql

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

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ù)庫(kù)連接
    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
    
    // 設(shè)置連接參數(shù)
    db.setHostName("localhost");      // 主機(jī)名
    db.setPort(5432);                 // 端口
    db.setDatabaseName("testdb");     // 數(shù)據(jù)庫(kù)名
    db.setUserName("postgres");       // 用戶名
    db.setPassword("password");       // 密碼
    
    // 打開連接
    if (!db.open()) {
        qDebug() << "數(shù)據(jù)庫(kù)連接失敗:" << db.lastError().text();
        return -1;
    }
    
    qDebug() << "成功連接到數(shù)據(jù)庫(kù)";
    
    // 關(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)建測(cè)試表

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

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ù)庫(kù)連接失敗:" << 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ù)庫(kù)
    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ù)庫(kù): " + 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ù)庫(kù)名、用戶名、密碼)
  • 檢查防火墻設(shè)置
  • 確保安裝了PostgreSQL客戶端庫(kù)

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

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

相關(guān)文章

  • PostgreSQL 備份與恢復(fù)實(shí)戰(zhàn)操作pg_dump / pg_restore 全方位指南

    PostgreSQL 備份與恢復(fù)實(shí)戰(zhàn)操作pg_dump / pg_restore 

    本文將帶你深入掌握 PostgreSQL 最核心的備份恢復(fù)工具 —— pg_dump 和 pg_restore,涵蓋邏輯備份、物理備份、增量備份、自動(dòng)化腳本等企業(yè)級(jí)實(shí)踐,感興趣的朋友跟隨小編一起看看吧
    2025-10-10
  • PostgreSQL行轉(zhuǎn)列的多種方法

    PostgreSQL行轉(zhuǎn)列的多種方法

    這篇文章主要介紹了PostgreSQL行轉(zhuǎn)列的多種方法,本文給大家分享三種方法,每種方法結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • PostgreSQL 恢復(fù)誤刪數(shù)據(jù)的操作

    PostgreSQL 恢復(fù)誤刪數(shù)據(jù)的操作

    這篇文章主要介紹了PostgreSQL 恢復(fù)誤刪數(shù)據(jù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • PostgreSQL 自定義自動(dòng)類型轉(zhuǎn)換操作(CAST)

    PostgreSQL 自定義自動(dòng)類型轉(zhuǎn)換操作(CAST)

    這篇文章主要介紹了PostgreSQL 自定義自動(dòng)類型轉(zhuǎn)換操作(CAST),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • PostgreSQL查看帶有綁定變量SQL的通用方法詳解

    PostgreSQL查看帶有綁定變量SQL的通用方法詳解

    今天我們要探討的是 custom執(zhí)行計(jì)劃和通用執(zhí)行計(jì)劃。這一技術(shù)在 Oracle中被稱為綁定變量窺視。但 Postgresql中并沒有這樣的定義,更嚴(yán)格地說,Postgresql叫做custom執(zhí)行計(jì)劃和通用執(zhí)行計(jì)劃
    2022-09-09
  • PostgreSQL數(shù)據(jù)目錄遷移的全過程

    PostgreSQL數(shù)據(jù)目錄遷移的全過程

    生產(chǎn)環(huán)境中隨著PostgreSQL數(shù)據(jù)庫(kù)表數(shù)據(jù)的不斷產(chǎn)生,數(shù)據(jù)庫(kù)目錄會(huì)不斷增長(zhǎng),當(dāng)磁盤空間不足時(shí)會(huì)有將PostgreSQL數(shù)據(jù)庫(kù)數(shù)據(jù)目錄遷移到其他目錄的需求,下面詳細(xì)介紹目錄遷移過程,需要的朋友可以參考下
    2024-04-04
  • PostgreSQL數(shù)據(jù)庫(kù)中DISTINCT關(guān)鍵字的四種用法詳解

    PostgreSQL數(shù)據(jù)庫(kù)中DISTINCT關(guān)鍵字的四種用法詳解

    PostgreSQL 不但高度兼容 SQL 標(biāo)準(zhǔn),同時(shí)還對(duì)很多語法進(jìn)行了擴(kuò)展,可以用于實(shí)現(xiàn)一些特殊的功能,今天我們就來介紹一下 PostgreSQL 數(shù)據(jù)庫(kù)中 DISTINCT 關(guān)鍵字的 4 種不同用法,需要的朋友可以參考下
    2024-04-04
  • 最新評(píng)論

    渝中区| 叙永县| 雷州市| 疏勒县| 东海县| 大埔县| 金寨县| 登封市| 东海县| 阿克苏市| 宝清县| 神池县| 南涧| 邵东县| 巴林右旗| 临沧市| 苏尼特左旗| 怀柔区| 武陟县| 米林县| 天镇县| 阿城市| 青州市| 博白县| 横山县| 民丰县| 措勤县| 南江县| 荆州市| 新乡市| 福建省| 通河县| 堆龙德庆县| 乌鲁木齐市| 南丰县| 杭锦后旗| 馆陶县| 山丹县| 台北市| 重庆市| 木里|