Qt-数据库开发-事务提交(3)
创始人
2024-03-30 03:36:08
0

Qt-数据库开发-通过QSqlTableModel显示和修改数据,开启事务

文章目录

  • Qt-数据库开发-通过QSqlTableModel显示和修改数据,开启事务
    • 1、概述
    • 2、实现效果
    • 3、主要代码
    • 4、完整源代码

更多精彩内容
👉个人内容分类汇总 👈
👉数据库开发 👈

1、概述

  • 这是通过学习Qt官方Demo产生的一个示例;
  • 通过自己理解加入了一些更加详细便于学习的内容;
  • 添加了非常详细的注释信息,对于小白更加友好。

开发环境说明

  • 系统:Windows10、Ubuntu20.04
  • Qt版本:V5.12.5
  • 编译器:MSVC2017-64、GCC/G++64

2、实现效果

  1. 通过QSqlTableModel将数据库内容直接显示到QTableView中,直观的显示和修改数据库中的数据;
  2. 程序启动时自动创建一个数据库,并创建一个表写入默认测试数据,可选择创建文件数据库还是内存数据库;
  3. 写入测试数据时演示了QSqlQuery的五种不同的插入数据方式;
  4. 在界面上修改内容后不会立即保存到数据库中,需要点击提交按键才一次性将所有修改的内容保存到数据库;
  5. 如果在界面上修改了内容,还没有提交事务时可以选择还原所有修改内容。
  • 实现效果如下:

    在这里插入图片描述

3、主要代码

  • 啥也不说了,直接上代码,一切有注释

  • pro文件: Qt使用到数据库,上来什么都别管,先在pro文件添加上QT += sql

  • main.cpp文件:程序第一次启动时在main函数中创建数据库并写入数据;

    #include "widget.h"#include 
    #include 
    #include 
    #include /*** @brief  创建并打开一个QSqlite数据库,并创建一个测试表person,同时默认创建5组数据* @return*/
    bool createConnection()
    {QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");  // 使用数据库驱动(Qsqlite)和默认连接名称(qt_sql_default_connection)添加一个数据库
    //    qDebug() << QSqlDatabase::defaultConnection;           // 打印默认数据库连接名称
    #if 1db.setDatabaseName("test.db");        // 使用文件数据库(可生成数据库文件,数据一直有效)
    #elsedb.setDatabaseName(":memory:");       // 使用内存数据库(不会生成数据库文件,所有数据都在内存中进行操作,性能强,程序退出后数据丢失)
    #endifif(!db.open())             // 打开数据库{QMessageBox::critical(nullptr, "Error", "打开数据库失败!");return false;}QSqlQuery query;          // 创建一个用于执行和操作Sql语句的对象// 创建一个表person,包含id、firstname、lastname三个字段query.exec("create table person (""id         int primary  key,"    // 索引"firstname  varchar(20),"         // 名"lastname   varchar(20))");       // 姓/****************** 向表中插入数据 ************************/// 插入方式一:直接插入数据query.exec("insert into person values(1, '悟空', '孙')");       // INSERT INTO 语法1(为表中所有项插入数据)// 插入方式二:使用命名占位符的[命名]绑定query.prepare("insert into person(id, firstname, lastname)"       // insert into 语法2"values (:id, :firstname, :lastname)");query.bindValue(":id", 2);query.bindValue(":firstname", "悟净");query.bindValue(":lastname", "沙");query.exec();// 插入方式三:使用命名占位符的[位置]绑定query.prepare("insert into person(id, firstname, lastname)"       // insert into 语法2"values (:id, :firstname, :lastname)");query.bindValue(0, 3);query.bindValue(1, "八戒");query.bindValue(2, "猪");query.exec();// 插入方式四:使用位置占位符绑定值(版本 1)query.prepare("insert into person(id, firstname, lastname)"       // insert into 语法2"values (?, ?, ?)");query.bindValue(0, 4);query.bindValue(1, "白龙");query.bindValue(2, "小");query.exec();// 插入方式五:使用位置占位符绑定值(版本 2)query.prepare("insert into person(id, firstname, lastname)"       // insert into 语法2"values (?, ?, ?)");query.addBindValue(5);                                           // 使用位置值绑定时,将值val添加到值列表中。addBindValue()调用的顺序决定了在准备好的查询中将值绑定到哪个占位符query.addBindValue("三藏");query.addBindValue("唐");query.exec();return true;
    }int main(int argc, char *argv[])
    {QApplication a(argc, argv);if(!createConnection()) return -1;    // 创建并打开一个数据库Widget w;w.show();return a.exec();
    }
  • widget.ui文件: 添加3个QPushButton用于提交和还原数据库事务、1个QTableView用于显示数据库内容;

    在这里插入图片描述

  • widget.h文件

    #ifndef WIDGET_H
    #define WIDGET_H#include 
    class QSqlTableModel;QT_BEGIN_NAMESPACE
    namespace Ui { class Widget; }
    QT_END_NAMESPACEclass Widget : public QWidget
    {Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_but_submit_clicked();void on_but_revert_clicked();void on_but_quit_clicked();private:Ui::Widget *ui;QSqlTableModel* m_model = nullptr;
    };
    #endif // WIDGET_H
  • widget.cpp文件

    #include "widget.h"
    #include "ui_widget.h"#include 
    #include 
    #include Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
    {ui->setupUi(this);this->setWindowTitle(QString("QSql-使用事务提交修改内容到数据库Demo - V%1").arg(APP_VERSION));m_model = new QSqlTableModel(this);m_model->setTable("person");         // 设置需要操作的表m_model->setEditStrategy(QSqlTableModel::OnManualSubmit);  // 设置数据不自动保存到数据库表m_model->select();                   // 查询表中所有数据ui->tableView->setModel(m_model);ui->tableView->resizeColumnsToContents();   // 根据表格中的内容自动调整列宽}Widget::~Widget()
    {delete ui;
    }/*** @brief 开启sqlite事务并提交修改,相对于直接使用submitAll更有优势(开始事务可以优化写入大量数据速度)*/
    void Widget::on_but_submit_clicked()
    {bool ret = m_model->database().transaction();if(!ret) return;if(m_model->submitAll())           // 提交所有修改,如果开启了事务,则保存到事务{m_model->database().commit();  // 如果开启了事务,则将事务保存到数据库QMessageBox::about(this, "注意!", "保存修改内容成功!");}else{m_model->database().rollback();QMessageBox::warning(this, "错误!", QString("数据提交错误:%1").arg(m_model->lastError().text()));}
    }/*** @brief 还原所有未提交的修改*/
    void Widget::on_but_revert_clicked()
    {m_model->revertAll();
    }/*** @brief 退出*/
    void Widget::on_but_quit_clicked()
    {this->close();
    }
    

4、完整源代码

  • github
  • gitee

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...