在Qt的数据库中,除了QSqlQuery访问数据库,还可以使用QSqlQueryModel,QSqlTableModel和QSqlRelationalTableModel,这三个类是从QAbstractTableModel派生下来的,可以很直观的查看数据库的数据
- QSqlQueryModel 提供一个只读模型
- QSqlTableModel 提供一个可以浏览和修改独立的SQL表
- QSqlRelationalTableModel 是QSqlTableModel的拓展,提供了对外键的支持
QSqlQueryModel的使用
因为继承自QAbstractTableModel,QSqlQueryModel拥有很多QAbstractTableModel的函数,这里就不在列举。
注意:QSqlQueryModel创建的是一个只读模型
QSqlQueryModel常用的函数:
setQuery() | 设置SQL语句 |
record() | 返回包含有关当前查询的字段的信息的记录 |
query() | 返回当前SQL语句 |
lastError() | 返回有关数据库上发生的最后一个错误的信息 |
clear() | 清除模型并释放资源 |
还有其他函数,可以自行查看帮助文档。
QSqlQueryModel *model=new QSqlQueryModel(this);
model->setQuery("select * from Person");//设置SQL语句
model->setHeaderData(0,Qt::Horizontal,tr("学号"));
model->setHeaderData(1,Qt::Horizontal,tr("名字"));
model->setHeaderData(2,Qt::Horizontal,tr("电话"));
model->setHeaderData(3,Qt::Horizontal,tr("年龄"));
model->setHeaderData(4,Qt::Horizontal,tr("身高"));
QTableView *view=new QTableView(this);//创建一个视图
view->setFixedSize(800,800);//设置视图大小
view->setModel(model);//添加模型
QSqlTableModel
QSqlTableModel 是一个高级接口,用于从单个表中读取和写入数据库记录。它建立在较低级别的QSqlQuery之上,可用于为QTableView等视图类提供数据。
注意该模型默认可读/写:需要设置只读的话,在视图中设置
View->setEditTriggers(QAbstractItemView::NoEditTriggers);
常用的函数:
tableName() | 返回当前选定表的名称 |
setSort() | 排序 |
setRecord() | 将值应用于模型中的行 |
setTable(name) | 将模型操作的数据库表设置为 name |
setFilter | 设置筛选器,筛选器是一个不带关键字的 SQL 子句 |
setEditStrategy() | 设置编辑数据库中的值的策略 |
setData() | 将角色角色的项索引的数据设置为值 |
selectStatement() | 返回内部用于填充模型的 SQL 语句。该语句包括筛选器和子句。SELECT ORDER BY |
revertRow() | 返回指定行的所有更改 |
removeRow() | 删除从行开始的计数行。由于此模型不支持分层结构,因此父模型必须是无效的模型索引 |
removeColumns() | 从父模型中删除计数列,从索引列开始 |
record() | 返回模型中行的记录。 |
primaryKey() | 返回主键 |
insertRecord() | 在位置行处插入记录。如果行为负数,则记录将追加到末尾 |
headData() | 标头 |
data() | 返回指定项和角色的值 |
select() | 以数据填充模型,使用指定的过滤器和排序条件,使用通过 setTable() 设置的表中的数据填充模型,如果成功则true,否则返回 false, 调用 select() 将还原任何未提交的更改并删除任何插入的列。 |
submit() | 当用户停止编辑当前行时,项目委托将调用此重新实现的槽 |
submitAll() | 提交所有挂起的更改,并在成功时返回 |
revert() | 当用户取消编辑当前行时,项目委托将调用此重新实现的槽 |
revertAll() | 还原所有挂起的更改 |
QSqlTableModel::EditStrategy(策略)
QSqlTableModel::OnFieldChange | 对模型的所有更改将立即应用于数据库 |
QSqlTableModel::OnRowChange | 当用户选择其他行时,将应用对行的更改 |
QSqlTableModel::OnManualSubmit | 所有更改都将缓存在模型中,直到调用 submitAll() 或 revertAll() |
QSqlTableModel访问数据库的方式有两种:
- 使用模型和视图
- 直接使用编程的方式直接访问,而无需将其绑定到视图
使用模型和视图:
QSqlTableModel *model=new QSqlTableModel(this);
model->setTable("Person");//设置访问的表
model->setEditStrategy(QSqlTableModel::OnManualSubmit);//设置策略
model->select();
model->setHeaderData(0,Qt::Horizontal,tr("学号"));
model->setHeaderData(1,Qt::Horizontal,tr("名字"));
model->setHeaderData(2,Qt::Horizontal,tr("电话"));
model->setHeaderData(3,Qt::Horizontal,tr("年龄"));
model->setHeaderData(4,Qt::Horizontal,tr("身高"));
QTableView *view=new QTableView(this);
view->setFixedSize(800,800);
view->setModel(model);
view->show();
使用使用编程的方式直接访问:
QSqlTableModel model;
model.setTable("Person");
model.select();
for(int i=0;i<model.rowCount();i++)
{
QSqlRecord p=model.record(i);
for(int j=0;j<p.count();j++)
{
qDebug()<<p.value(j);
}
}
一些函数的使用:
1.使用排序
QSqlTableModel *model=new QSqlTableModel(this);
model->setTable("Person");//设置访问的表
model->setEditStrategy(QSqlTableModel::OnManualSubmit);//设置策略
model->select();
model->setHeaderData(0,Qt::Horizontal,tr("学号"));
model->setHeaderData(1,Qt::Horizontal,tr("名字"));
model->setHeaderData(2,Qt::Horizontal,tr("电话"));
model->setHeaderData(3,Qt::Horizontal,tr("年龄"));
model->setHeaderData(4,Qt::Horizontal,tr("身高"));
model->setSort(0,Qt::DescendingOrder);//按照第一列进行降序排序
model->select();//重新显示数据
QTableView *view=new QTableView(this);
view->setFixedSize(800,800);
view->setModel(model);
view->show();
2.使用筛选
QSqlTableModel *model=new QSqlTableModel(this);
model->setTable("Person");//设置访问的表
model->setEditStrategy(QSqlTableModel::OnManualSubmit);//设置策略
model->select();
model->setHeaderData(0,Qt::Horizontal,tr("学号"));
model->setHeaderData(1,Qt::Horizontal,tr("名字"));
model->setHeaderData(2,Qt::Horizontal,tr("电话"));
model->setHeaderData(3,Qt::Horizontal,tr("年龄"));
model->setHeaderData(4,Qt::Horizontal,tr("身高"));
model->setFilter(QString("name='%1'").arg("李"));//筛选 名字为 李的数据
model->select();
QTableView *view=new QTableView(this);
view->setFixedSize(800,800);
view->setModel(model);
view->show();
在ui->界面中添加3个按钮,分别为保存更改,撤销更改,删除选中行
函数的实现:
connect(ui->pushButton,&QPushButton::clicked,this,[=]()//保存更改
{
model->submitAll();//保存
//这里的话可以使用事务,但这里就不举例了
});
connect(ui->pushButton_2,&QPushButton::clicked,this,[=]()//撤销更改
{
model->revertAll();//撤销
});
connect(ui->pushButton_3,&QPushButton::clicked,this,[=]()//删除选中行
{
int row=view->currentIndex().row();//获取当前行数
model->removeRow(row);//删除当前行
model->submitAll();//保存
});
初始状态:
修改数据并保存:
撤销就不演示了
删除选中行:选中最后一行,点击删除
还有很多函数,这里就不介绍了,可以自行测试和使用。
QSqlRelationalTableModel
QSqlRelationalTableModel继承自QSqlTableModel,提供了对外键的支持
常用函数:
relation() | 返回列的关系 |
relationMode() | 返回一个 QSqlTableModel 对象,用于访问列是其外键的表,或者如果给定列没有关系 |
select() | 以数据填充模型 |
removeColumns() | 移除列 |
setData() | 将具有指定索引的项目中角色的数据设置为给定的值 |
setJoinMode() | 设置 SQL 联接模式以显示或隐藏具有 NULL 外键的行 |
setRelation() | 允许指定的列是关系指定的外部索引 |
setTable() | 设置表 |
setRelation(int column, const QSqlRelation &relation) 用于两个表之间创建一个关系
QSqlRelationalTableModel *model=new QSqlRelationalTableModel(this);
model->setTable("Person");
model->setRelation(0,QSqlRelation("People","name","age"));
model->setEditStrategy(QSqlTableModel::OnManualSubmit);//设置策略
model->select();
QTableView *view=new QTableView(this);
view->setModel(model);
model->setRelation(0,QSqlRelation("People","name","age"));
- 0为列数
- People 为相关联的表
- name为外键
- age为在0列显示的People中的数据
在Qt中还提供一个委托类,会使用一个QComBoBox来显示数据库中该类的数据,使得方便修改数据 。
代码如下:
view->setItemDelegate(new QSqlRelationDelegate(view));