【Qt】数据库实战之QSqlTableModel模型

00. 目录

01. 概述

只读的QSqlQueryModel模型其实也可以实现编辑功能的,但是实现起来很麻烦。而QSqlTableModel提供了一个一次只能操作单个SQL表的读写模型,它是QSqlQuery的更高层次的替代品,可以浏览和修改独立的SQL表,并且只需编写很少的代码,而且不需要了解SQL语法。

02. 开发环境

Windows系统:Windows10

Qt版本:Qt5.15或者Qt6

03. QSqlTableModel基本操作

3.1 新建Qt Widgets应用,项目名称为16SQL,基类为QMainWindow,类名MainWindow。

3.2 在16SQL.pro文件中添加一下模块

QT       += sql

3.3 向项目中添加新的C++头文件,名称为connection.h。

#ifndef CONNECTION_H
#define CONNECTION_H

#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>

static bool createConnection()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("test.db");
    if (!db.open())
    {
        return false;
    }

    QSqlQuery query;
    query.exec("create table student(id int primary key, name varchar(20))");
    query.exec("insert into student values(1, ' 王鹏')");
    query.exec("insert into student values(2, '李刚')");
    query.exec("insert into student values(3, '李强')");
    query.exec("insert into student values(4, '王强')");
    query.exec("insert into student values(5, '黎明朗')");

    return true;
}

#endif // CONNECTION_H

3.4 main.cpp文件更改如下

#include "mainwindow.h"

#include <QApplication>
#include "connection.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    if (!createConnection())
    {
        return 1;
    }


    MainWindow w;
    w.show();
    return a.exec();
}

3.5 进行界面设计,界面设计如下
在这里插入图片描述

3.6 mainwindow.h文件中,先包含头文件和私有对象

#include <QSqlTableModel>

private:
    QSqlTableModel *model;

3.7 在构造函数添加如下代码

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    model = new QSqlTableModel(this);
    model->setTable("student");
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);

    //不显示第二列
    //model->removeColumn(1);

    //查询整张表
    model->select();

    ui->tableView->setModel(model);

    //设置视图不可编辑
    //ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
}

这里创建一个QSqlTableModel后,只需使用setTable()来为其指定数据表,然后使用select()函数进行查询,调用这两个函数就等价于执行了“select * from student”这个SQL语句。这里还可以使用setFilter()来指定查询时的条件,在后面会看到这个函数的使用。在使用该模型以前,一般还要设置其编辑策略,它由QSqlTableModel::EditStrategy枚举类型定义,一共有三个值,如下图所示。用来说明当数据库中的值被编辑后,什么情况下提交修改。
在这里插入图片描述

执行结果如下:
在这里插入图片描述

04. QSqlTableModel修改操作

4.1 “提交修改”按钮的单击信号槽,更改如下:

//提交修改
void MainWindow::on_pushButton_clicked()
{
    //开启事务
    model->database().transaction();
    if (model->submitAll())
    {
        //提交事务
        model->database().commit();
    }
    else
    {
        //回滚事务
        model->database().rollback();
        QMessageBox::warning(this, tr("TableView"), tr("数据库错误: %1").arg(model->lastError().text()));
    }
}

model->submitAll()提交所有更改。

4.2 撤销修改按钮槽函数

//撤销修改
void MainWindow::on_pushButton_2_clicked()
{
    model->revertAll();
}

现在运行程序,我们将“third”改为“three”,如果我们点击“撤销修改”,那么它就会重新改为“陈third”,而当我们点击“提交修改”后它就会保存到数据库,此时再点击“撤销修改”就修改不回来了。

​ 可以看到,这个模型可以将所有修改先保存到model中,只有当我们执行提交修改后,才会真正写入数据库。当然这也是因为我们在最开始设置了它的保存策略:

//OnManualSubmit表明我们要提交修改才能使其生效。
model->setEditStrategy(QSqlTableModel::OnManualSubmit);

05. QSqlTableModel查询操作

5.1 查询按钮槽函数

//查询按钮
void MainWindow::on_pushButton_5_clicked()
{
    QString name = ui->lineEdit->text();

    //根据姓名进行筛选
    model->setFilter(QString("name = %1").arg(name));

    //显示结果
    model->select();
}

使用setFilter()函数进行关键字筛选,这个函数是对整个结果集进行查询。

5.2 显示全表按钮槽函数

//显示全表按钮槽函数
void MainWindow::on_pushButton_6_clicked()
{
    //设置要查询的表
    model->setTable("student");
    //执行查询操作
    model->select();
}

06. QSqlTableModel排序操作

按ID升序排序按钮槽函数

//根据ID进行升序排序操作
void MainWindow::on_pushButton_7_clicked()
{
    model->setSort(0, Qt::AscendingOrder);
    
    model->select();
}

按ID降序排序按钮槽函数

//根据ID进行降序排序操作
void MainWindow::on_pushButton_8_clicked()
{
    model->setSort(0, Qt::DescendingOrder);

    model->select();
}

setSort()函数进行排序,它有两个参数,第一个参数表示按第几个字段排序,表头从左向右,最左边是第0个字段,这里就是id字段。第二个参数是排序方法,有升序和降序两种。

07. QSqlTableModel删除操作

删除选中行按钮槽函数实现如下

//删除选中行
void MainWindow::on_pushButton_4_clicked()
{
    //获取选中的行
    int curRow = ui->tableView->currentIndex().row();

    //删除该行
    model->removeRow(curRow);

    int ret = QMessageBox::warning(this, tr("删除当前行"), tr("你确定要删除该行吗"), QMessageBox::Yes | QMessageBox::No);
    if (ret == QMessageBox::Yes)
    {
        //删除该行 提交到数据库
        model->submitAll();
    }
    else
    {
        //不删除  撤销操作
        model->revertAll();
    }
}

删除行的操作会先保存在model中,当我们执行了submitAll()函数后才会真正的在数据库中删除该行。这里我们使用了一个警告框来让用户选择是否真得要删除该行。执行程序效果如下:
在这里插入图片描述

我们单击第三行,然后单击“删除选中行”按钮,出现了警告框。这时你会发现,表中的第三行前面出现了一个小感叹号,表明该行已经被修改了,但是还没有真正在数据库中修改,这时的数据有个学名叫脏数据(Dirty Data)。当我们按钮“Yes”按钮后数据库中的数据就会被删除,如果按下“No”,那么更改就会取消。

08. QSqlTableModel插入操作

添加记录槽函数实现如下

//添加记录
void MainWindow::on_pushButton_3_clicked()
{
    //获取表的行数
    int row = model->rowCount();

    int id = 18;
    //添加一行
    model->insertRow(row);

    model->setData(model->index(row, 0), id);
    model->setData(model->index(row, 1), tr("李华"));

    //提交
    //model->submitAll();
}

在表的最后添加一行,因为在student表中我们设置了id号是主键,所以这里必须使用setData()函数给新加的行添加id字段的值,不然添加行就不会成功。这里可以直接调用submitAll()函数进行提交,也可以利用“提交修改”按钮进行提交。

09. QSqlTableModel总结

QSqlTableModel模型很强大,而且完全脱离了SQL语句,就算你不怎么懂数据库知识,也可以利用它进行大部分常用的操作。我们也看到了,这个模型提供了缓冲区,可以先将修改保存起来,当我们执行提交函数时,再去真正地修改数据库。

10. 附录

10.1 Qt教程汇总
网址:https://dengjin.blog.csdn.net/article/details/115174639

10.2 源码下载
网址:【Qt】数据库实战之QSqlTableModel模型.rar

© 版权声明
THE END
喜欢就支持一下吧
点赞940 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容