亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

一、環(huán)境準備

1. 安裝 PostgreSQL

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

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

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

3. 配置 Qt 連接 PostgreSQL

在項目文件(.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");      // 主機名
    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);
}

三、實現(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);
    
    // 使用預處理語句防止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. 使用控制臺程序演示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è)要刪除ID為1的員工
    
    if (!query.exec()) {
        qDebug() << "刪除失敗:" << query.lastError().text();
    } else {
        qDebug() << "刪除成功";
    }
    
    closeDatabase(db);
    return a.exec();
}

2. 使用Qt Widgets實現(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, "錯誤", "無法連接到數(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);
 
    // 連接信號槽
    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, "錯誤", "保存失敗: " + 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, "錯誤", "保存失敗: " + model->lastError().text());
        }
    }
}
 
void EmployeeForm::on_deleteButton_clicked()
{
    QModelIndex index = ui->tableView->currentIndex();
    if (index.isValid()) {
        int ret = QMessageBox::question(this, "確認", "確定要刪除這條記錄嗎?",
                                        QMessageBox::Yes | QMessageBox::No);
        if (ret == QMessageBox::Yes) {
            model->removeRow(index.row());
            if (!model->submitAll()) {
                QMessageBox::warning(this, "錯誤", "刪除失敗: " + model->lastError().text());
                model->revertAll();
            }
        }
    }
}
 
void EmployeeForm::on_refreshButton_clicked()
{
    model->select();
}

五、高級功能

1. 事務(wù)處理

bool performTransaction(QSqlDatabase &db) {
    db.transaction();
    
    QSqlQuery query(db);
    bool success = true;
    
    // 執(zhí)行多個操作
    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. 使用存儲過程

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)用存儲過程失敗:" << query.lastError().text();
        return false;
    }
    
    return true;
}

六、常見問題解決

1. 連接失敗

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

2. 中文亂碼

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

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

db.setConnectOptions("client_encoding=UTF8");

3. 性能優(yōu)化

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

七、總結(jié)

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

以上就是QT操作PostgreSQL數(shù)據(jù)庫并實現(xiàn)增刪改查功能的詳細內(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如何查詢重復計數(shù)及去重查詢

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

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

    sqoop 實現(xiàn)將postgresql表導入hive表

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

    PostgreSQL 正則表達式替換-使用變量方式

    這篇文章主要介紹了PostgreSQL 正則表達式替換-使用變量方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    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ù)庫中用于截斷日期部分的函數(shù),文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    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標準建表語句分享

    PostgreSQL標準建表語句分享

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

    springboot 沒法掃描到repository的解決

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

    postgresql修改自增序列操作

    這篇文章主要介紹了postgresql修改自增序列操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    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ù))三個字段,建表后,可通過insert語句插入數(shù)據(jù),這種反向操作有助于從現(xiàn)有數(shù)據(jù)結(jié)構(gòu)出發(fā),快速構(gòu)建數(shù)據(jù)庫表,并進行數(shù)據(jù)填充,感興趣的朋友跟隨小編一起看看吧
    2022-02-02

最新評論