【Qt】数据库用户接口层

165 篇文章 393 订阅

00. 目录

01. 概述

用户接口层主要包括Qt SQL模块中的QSqlQueryModel、QSqlTableModel、QSqlRelationalTableModel。用户接口层的类实现了将数据库中的数据链接到窗口部件上,是使用模型/视图框架实现的,是更高层次的抽象,即便不熟悉SQL也可以操作数据库。需要注意的是,在使用用户接口层的类之前必须先实例化QCoreApplication对象。

QT中使用了自己的机制来避免使用SQL语句,提供了更简单的数据库操作及数据显示模型,分别是只读的QSqlQueryModel、操作单表的QSqlTableModel和支持外键的QSqlRelationalTableModel。

02. 开发环境

Windows系统:Windows10

Qt版本:Qt5.15或者Qt6

03. QSqlQueryModel类

3.1 QSqlQueryModel类简介

QSqlQueryModel类为SQL结果集提供了只读的数据模型,是执行SQL语句和遍历结果集的高级接口。QSqlQueryModel基于下层的QSqlQuery构建,用于提供数据给QTableView等视图类。

QSqlQueryModel模型默认是只读的,通过QSqlQueryModel派生自定义类重写setData()和flags()函数可以实现读写,或是使用QSqlTableModel。

3.2 QSqlQueryModel类常用成员函数

QSqlQueryModel(QObject *parent = nullptr)
    使用给定的parent创建一个空的QSqlQueryModel 。
virtual	~QSqlQueryModel()
    销毁对象并释放所有分配的资源。
virtual void	clear()
    清除模型并释放所有获取的资源。
QSqlError	lastError() const
    返回有关数据库上发生的最后一个错误的信息。
QSqlQuery	query() const
    返回与此模型关联的QSqlQuery。
QSqlRecord	record(int row) const
    返回包含有关当前查询的字段信息的记录。如果row是有效行的索引,则将使用该行中的值填充记录。
	如果未初始化模型,则将返回空记录。
QSqlRecord	record() const
    返回一个空记录,其中包含有关当前查询的字段的信息。
	如果未初始化模型,则将返回空记录。
void	setQuery(const QSqlQuery &query)
    重置模型并将数据提供者设置为给定查询。请注意,查询必须处于活动状态,并且不能为isForwardOnly()。	
	如果设置查询时发生错误,lastError()可用于检索详细信息。
void	setQuery(const QString &query, const QSqlDatabase &db = QSqlDatabase())
    对给定的数据库连接db执行查询查询。如果未指定数据库(或无效的数据库),则使用默认连接。
	如果设置查询时发生错误,lastError()可用于检索详细信息。
    
virtual QModelIndex	indexInQuery(const QModelIndex &item) const
    返回模型中给定项目的数据库结果集中的值的索引。
	如果未插入,删除或移动任何列或行,则返回值与item相同。
	如果item超出范围或item没有指向结果集中的值,则返回无效的模型索引。
virtual void	queryChange()
    每当查询更改时,都会调用此虚拟函数。默认实现不执行任何操作。
void	setLastError(const QSqlError &error)
    该函数允许派生类将数据库上发生的最后一个错误的值设置为error。

程序示例一:

    QSqlQueryModel *model = new QSqlQueryModel;
    model->setQuery("SELECT name, salary FROM employee");
    model->setHeaderData(0, Qt::Horizontal, tr("Name"));
    model->setHeaderData(1, Qt::Horizontal, tr("Salary"));
    QTableView *view = new QTableView;
    view->setModel(model);
    view->show();

3.3 自定义QSqlQueryModel

​ QSqlQueryModel默认是只读的,在窗口上并不能对表格中的内容进行修改。如果要按照自己的需要显示数据和修改数据,可以创建自己的模型。要想使其可读

写,需要自己的类继承自QSqlQueryModel,并且重写setData()和flags()两个函数。如果要改变数据的显示,就要重写data() 函数。

Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
QVariant data(const QModelIndex &item, int role=Qt::DisplayRole) const;

04. QSqlTableModel类

4.1 QSqlTableModel类简介

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

QSqlTableModel类为单个数据库表提供了可编辑的数据模型,是从单个表中读写数据库记录的高级接口。QSqlTableModel基于下层的QSqlQuery构建,用于提供数据给QTableView等视图类。

4.2 QSqlTableModel类常用成员方法

QSqlTableModel::QSqlTableModel(QObject *parent = Q_NULLPTR, QSqlDatabase db = QSqlDatabase())
构建一个QSqlTableModel空对象,设置父对象为parent,数据库连接为db,如果db非法,使用默认数据库连接。

[signal] void QSqlTableModel::beforeDelete(int row)
[signal] void QSqlTableModel::beforeInsert(QSqlRecord &record)
[signal] void QSqlTableModel::beforeUpdate(int row, QSqlRecord &record)

QSqlDatabase QSqlTableModel::database() const
返回模型的数据库连接

[virtual protected] bool QSqlTableModel::deleteRowFromTable(int row)
从当前活跃的数据库表中删除给定的行

EditStrategy QSqlTableModel::editStrategy() const
返回当前的编辑策略

int QSqlTableModel::fieldIndex(const QString &fieldName) const
返回字段名为fieldName的字段的索引,如果没有相应字段返回-1

QString QSqlTableModel::filter() const
返回当前设置的过滤器

bool QSqlTableModel::insertRecord(int row, const QSqlRecord &record)
在row行插入一条记录record,如果row为负数,追加到尾部

bool QSqlTableModel::isDirty(const QModelIndex &index) const
如果index位置的值是脏值,返回true。脏值是被模型修改单尚未写入数据库的值

bool QSqlTableModel::isDirty() const
如果模型包含被修改的值并且没有提交到数据库,返回true

QSqlIndex QSqlTableModel::primaryKey() const
返回当前表的主键

程序示例一:结合模型视图显示

    QSqlTableModel *model = new QSqlTableModel;
    model->setTable("employee");
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();
    model->setHeaderData(0, Qt::Horizontal, tr("Name"));
    model->setHeaderData(1, Qt::Horizontal, tr("Salary"));

    QTableView *view = new QTableView;
    view->setModel(model);
    view->hideColumn(0); // don't show the ID
    view->show();

程序示例二:通过模型直接访问数据

 	QSqlTableModel model;
    model.setTable("employee");
    model.select();
    int salary = model.record(4).value("salary").toInt();

程序示例三:增删改查


//查询操作
QString name = lineedit->text();
//根据姓名进行筛选
model->setFilter(QString("name = '%1'").arg(name));
//显示结果
model->select();
model->setTable("student"); //重新关联表
model->select();//选择整个表格


//排序操作
//升序:
model->setSort(0, Qt::AscendingOrder); //id属性即第0列,升序排列
model->select();

//降序:
model->setSort(0, Qt::DescendingOrder);
model->select();


//删除操作
//获取选中的行
int curRow = view->currentIndex().row();
//删除该行
model->removeRow(curRow);
int ok = QMessageBox::warning(this,tr("删除当前行!"),tr("你确定删除当前行吗?"),
			QMessageBox::Yes,QMessageBox::No);
if(ok == QMessageBox::No)
{
    model->revertAll(); //如果不删除,则撤销
}
else
    model->submitAll(); //否则提交,在数据库中删除该行


//插入操作
int rowNum = model->rowCount(); //获得表的行数
int id = 10;
model->insertRow(rowNum); //添加一行
model->setData(model->index(rowNum,0),id);

05. QSqlRelationalTableModel类

5.1 QSqlRelationalTableModel简介

QSqlRelationalTableModel为了单个数据库表格提供了可编辑的数据模型。

QSqlRelationalTableModel继承自QSqlTableModel,并对其进行了扩展,提供了对外键的支持。外键就是一个表中的一个属性和其他表中的主键属性之间的一对一的映射。

5.2 QSqlRelationalTableModel常用成员方法

[virtual] void QSqlRelationalTableModel::setRelation(int column, const QSqlRelation &relation)
当前表中第column列为QSqlRelation(tableName,indexColumn,displayColumn)的外键

QVariant QSqlRelationalTableModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const
返回index的数据

[virtual protected] bool QSqlRelationalTableModel::insertRowIntoTable(const QSqlRecord &values)
向表中插入一条记录values

QSqlRelation QSqlRelationalTableModel::relation(int column) const
返回表格中第column列的关系

[virtual] QSqlTableModel *QSqlRelationalTableModel::relationModel(int column) const
返回外键column要访问的表的QSqlTableModel对象

[virtual] bool QSqlRelationalTableModel::setData(const QModelIndex &index, const QVariant &value, 
int role = Qt::EditRole)
设置index数据项的值为value,数据项角色为role

[virtual] void QSqlRelationalTableModel::setTable(const QString &table)
设置模型的表格为table

程序示例:

     model->setTable("employee");

     model->setRelation(2, QSqlRelation("city", "id", "name"));
     model->setRelation(3, QSqlRelation("country", "id", "name"));

06. QSqlRelationalDelegate类

6.1 QSqlRelationalDelegate类简介

为了控制表中某些数据项的数据的可选类型或是数据内容,可以使用委托。QT提供了QSqlRelationalDelegate委托类,可以为QSqlRelationalTableModel显示和编辑数据。不同于默认的委托,QSqlRelationalDelegate为外键提供了字段的下拉框。

程序示例:

     std::unique_ptr<QTableView> view{new QTableView};
     view->setModel(model);
     view->setItemDelegate(new QSqlRelationalDelegate(view.get()));

07. 附录

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
网管教程 从入门到精通软件篇 ★一。★详细的xp修复控制台命令和用法!!! 放入xp(2000)的光盘,安装时候选R,修复! Windows XP(包括 Windows 2000)的控制台命令是在系统出现一些意外情况下的一种非常有效的诊断和测试以及恢复系统功能的工具。小编的确一直都想把这方面的命令做个总结,这次辛苦老范给我们整理了这份实用的秘笈。   Bootcfg   bootcfg 命令启动配置和故障恢复(对于大多数计算机,即 boot.ini 文件)。   含有下列参数的 bootcfg 命令仅在使用故障恢复控制台时才可用。可在命令提示符下使用带有不同参数的 bootcfg 命令。   用法:   bootcfg /default  设置默认引导项。   bootcfg /add    向引导列表中添加 Windows 安装。   bootcfg /rebuild  重复全部 Windows 安装过程并允许用户选择要添加的内容。   注意:使用 bootcfg /rebuild 之前,应先通过 bootcfg /copy 命令备份 boot.ini 文件。   bootcfg /scan    扫描用于 Windows 安装的所有磁盘并显示结果。   注意:这些结果被静态存储,并用于本次会话。如果在本次会话期间磁盘配置发生变化,为获得更新的扫描,必须先重新启动计算机,然后再次扫描磁盘。   bootcfg /list   列出引导列表中已有的条目。   bootcfg /disableredirect 在启动引导程序中禁用重定向。   bootcfg /redirect [ PortBaudRrate] |[ useBiosSettings]   在启动引导程序中通过指定配置启用重定向。   范例: bootcfg /redirect com1 115200 bootcfg /redirect useBiosSettings   hkdsk   创建并显示磁盘的状态报告。Chkdsk 命令还可列出并纠正磁盘上的错误。   含有下列参数的 chkdsk 命令仅在使用故障恢复控制台时才可用。可在命令提示符下使用带有不同参数的 chkdsk 命令。   vol [drive:] [ chkdsk [drive:] [/p] [/r]   参数  无   如果不带任何参数,chkdsk 将显示当前驱动器中的磁盘状态。 drive: 指定要 chkdsk 检查的驱动器。 /p   即使驱动器不在 chkdsk 的检查范围内,也执行彻底检查。该参数不对驱动器做任何更改。 /r   找到坏扇区并恢复可读取的信息。隐含着 /p 参数。   注意 Chkdsk 命令需要 Autochk.exe 文件。如果不能在启动目录(默认为 %systemroot%System32)中找到该文件,将试着在 Windows 安装 CD 中找到它。如果有多引导系统的计算机,必须保证是在包含 Windows 的驱动器上使用该命令。 Diskpart   创建和删除硬盘驱动器上的分区。diskpart 命令仅在使用故障恢复控制台时才可用。   diskpart [ /add |/delete] [device_name |drive_name |partition_name] [size]   参数 无   如果不带任何参数,diskpart 命令将启动 diskpart 的 Windows 字符模式版本。   /add   创建新的分区。   /delete   删除现有分区。   device_name   要创建或删除分区的设备。设备名称可从 map 命令的输出获得。例如,设备名称:   DeviceHardDisk0   drive_name   以驱动器号表示的待删除分区。仅与 /delete 同时使用。以下是驱动器名称的范例:   D:   partition_name   以分区名称表示的待删除分区。可代替 drive_name 使用。仅与 /delete 同时使用。以下是分区名称的范例:   DeviceHardDisk0Partition1    大小   要创建的分区大小,以兆字节 (MB)表示。仅与 /add 同时使用。   范例   下例将删除分区: diskpart /delete Device HardDisk0 Partition3 diskpart /delete F:   下例将在硬盘上添加一个 20 MB 的分区:   diskpart /add Device HardDisk0 20   Fixboot

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值