QSqlTableModel
The QSqlTableModel class provides an editable data model for a single database table.
QSqlTableModel is a high-level interface for reading and writing database records from a single table. It is built on top of the lower-level QSqlQuery and can be used to provide data to view classes such as QTableView.
示例:
QSqlTableModel *model = new QSqlTableModel(parentObject, database);
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();
由上一篇博客:
http://blog.youkuaiyun.com/u013402772/article/details/55212464
可以看出虽然可以使用 QSqlQueryModel
来实现可编辑功能,但是实现起来比较麻烦。QSqlTableModel
提供了一个一次只能操作单个SQL表的读写模型,它是QSqlQuery
的更高层次的替代品,可以浏览和修改独立的SQL表,并且只需编写很少的代码,而且不需要了解SQL语法。
写了一个Demo 包含了一些常用的操作:
界面如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QSqlError>
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->select(); //查询整张表
ui->tableView->setModel(model);
//ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
}
MainWindow::~MainWindow()
{
delete ui;
}
这里创建一个QSqlTableModel
后,只需使用setTable()
来为其指定数据库表,然后使用select()
函数进行查询,调用这两个函数就等价于执行了select * from student
这个SQL语句。这里还可以使用setFilter()
来指定查询时的条件,在后面会看到这个函数的使用。
在使用该模型以前,一般还要设置其编辑策略,它由QSqlTableModel::EditStrategy
枚举变量定义,一共有三个值,如下图所示。用来说明当数据库中的值被编辑后,什么情况下提交修改。
//提交修改
void MainWindow::on_pushButton_clicked(bool checked)
{
model->database().transaction();//开始事物操作
if(model->submitAll())
model->database().commit();
else{
model->database().rollback(); //回滚
QMessageBox::warning(this,tr("tableModel"),
QStringLiteral("数据库错误:")+tr("%1").arg(model->lastError().text()));
}
}
//撤销修改
void MainWindow::on_pushButton_2_clicked(bool checked)
{
model->revertAll();
//如果提交了数据库就修改不了了
}
//查询
void MainWindow::on_pushButton_7_clicked()
{
QString name = ui->lineEdit->text();
//筛选
model->setFilter(QString("name = '%1'").arg(name));
//查询
model->select();
}
//显示全表
void MainWindow::on_pushButton_8_clicked()
{
//重新关联
model->setTable("student");
//查询
model->select();
}
//按id升序
void MainWindow::on_pushButton_5_clicked()
{
model->setSort(0,Qt::AscendingOrder); //第0列升序排列
model->select();
}
//按id 降序
void MainWindow::on_pushButton_6_clicked()
{
model->setSort(0,Qt::DescendingOrder);//第0列降序
model->select();
}
//删除选中行
void MainWindow::on_pushButton_4_clicked()
{
//获取选中行
int curRow = ui->tableView->currentIndex().row();
//删除该行
model->removeRow(curRow); //只是model中删除,还未提交到数据库
int ok = QMessageBox::warning(this,QStringLiteral("删除当前行"),
QStringLiteral("确定与否?"),
QMessageBox::Yes,QMessageBox::No);
if(ok == QMessageBox::No)
model->revertAll();
else
model->submitAll();
}
//添加记录
void MainWindow::on_pushButton_3_clicked()
{
int rowCount = model->rowCount();
int id = 10;
model->insertRow(rowCount);
model->setData(model->index(rowCount,0),id);
//model->submit();
}
在表的最后添加一行,因为在student表中我们设置了id号是主键,所以这里必须使用setData()
函数给新加的行添加id属性的值,不然添加行就不会成功。这里可以直接调用submitAll()
函数进行提交,也可以利用“提交修改”按钮进行提交。
总结:
可以看到这个模型很强大,而且完全脱离了SQL语句,就算不怎么懂数据库知识,也可以利用它进行大部分常用的操作。我们也看到了,这个模型提供了缓冲区,可以先将修改保存起来,当我们执行提交函数时,再去真正地修改数据库。当然,这个模型比前面的模型更高级,前面讲的所有操作,在这里都能执行。