QSqlTableModel是一个可以很方便实现数据库增删改,以及一些自定义sql操作的工具,尤其是数据库数据修改,利用QSqlTableModel+QTableView可以非常的方便且只管。
利用QSqlTableModel模型及QTableView实现数据库增删改
一、准备工作
1 创建QSqlDatabase
涉及的所有头文件:
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QCoreApplication>
#include <QDir>
#include <QMessageBox>
#include <QSqlTableModel>
#include <QSqlRecord>
声明:
QSqlDatabase *mQSqlDatabase=new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE","test_database"));
定义:
//笔者使用的是qt自带的QSqlite,找到要打开的db文件
QString path=QCoreApplication::applicationDirPath()+"/Data";
QDir dir(path);
if(!dir.exists()){
dir.mkpath(path);
}
QString dbpath = path +"/database.db";
mQSqlDatabase->setDatabaseName(dbpath);//如果没有这个数据库,则会创建
if(!mQSqlDatabase->open()){
QMessageBox::warning(this,"警告","数据库打开失败!");
}
2 创建QSqlTableModel模型
声明:
QSqlTableModel* model;
定义:
//将QSqlTableModel与QSqlDatabase绑定起来
model = new QSqlTableModel(this,*mQSqlDatabase);
model->setTable("test");
model->setSort(1,Qt::DescendingOrder);//降序排列
//下面这句很重要,设置数据库修改后保存的方式,默认应该是OnFieldChange,即编辑完就保存修改至数据库,OnManualSubmit是需要手动提交时
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
//刷新任务列表
ui->tableView->setModel(model);
ui->tableView->resizeColumnsToContents();//自动调整列宽
ui->tableView->resizeRowsToContents();//自动调整行距
ui->tableView->setAlternatingRowColors(true);//设置行间交叉颜色
ui->tableView->setColumnHidden(0,true);//设置某一列不显示
3 创建表格
if(!mQSqlDatabase->tables().contains("test")){
bool si=query.exec("create table test(id integer Primary key,Code varchar(32))");
if(!si){
emit warnInfo("数据表创建失败!"+query.lastError().text());
}
}
二、实现数据库操作
1 增
QSqlRecord record = model->record();
//"filedName"就是列名,后面跟着的是相应的值
record.setValue("filedName",ui->lineEdit->text());
model->insertRecord(0,record);//每次都从第一列插入
model->submitAll();//如果设置保存策略是OnManualSubmit,则需要每次都提交一次修改
model->select();//每次对数据库有什么变动,都应该重新筛选一次,获取最新的数据
2 删
如果保存策略是OnManualSubmit
int curRow=ui->tableView->currentIndex().row();
model->removeRow(curRow);
int ok=QMessageBox::warning(this,"确定?","删否?",QMessageBox::Yes,QMessageBox::No);
if(ok==QMessageBox::Yes)
{
model->submitAll();//提交策略
}else{
model->revertAll();//回退,注意,只有在保存策略是OnManualSubmit时有用
}
model->select();
否则,应该这么写
int curRow=ui->tableView->currentIndex().row();
int ok=QMessageBox::warning(this,"确定?","删否?",QMessageBox::Yes,QMessageBox::No);
if(ok==QMessageBox::Yes)
{
model->removeRow(curRow);
model->submitAll();//提交策略
}
model->select();
3 改
利用QSqlTableModel模型及QTableView模型,最方便的就是改的操作,直接可视化执行,然后保存即可。即在表格中直接修改,然后提交修改即可。
修改完后,如下提交:
model->database().transaction();
if(model->submitAll()){
model->database().commit();
}else{
model->database().rollback();
QString str;
str += model->lastError().text();
QMessageBox::warning(this,"error",str);
}
4 带条件的筛选
如果是获取全部数据,则直接**model->select()**即可,但有时候只想要指定条件的内容,则可以使用
QString find = QString("Code='%1'").arg(ui->Task_comboBox->currentText());
model->setFilter(find);//添加筛选条件
model->select();
5 自定义数据库操作
QSqlQuery query(*mQSqlDatabase);
int curRow = ui->tableView->currentIndex().row();
QModelIndex index = ui->tableView->model()->index(curRow,0);
QString id = ui->tableView->model()->data(index).toString();
int tid = id.toInt();
QString d = QString("delete from %1 where id = %2").arg("test").arg(tid);
if(!query.exec(d)){
QString str;
str += query.lastError().text();
QMessageBox::warning(this,"error",str);
}
三、经验总结
- 一定要谨慎设置好**model->setEditStrategy(QSqlTableModel::OnManualSubmit)**这个保存策略,我一开始没指定submit才保存,所以每次删除后都无法回退revert。如果设置除此别的模式,那是不需要submit就能保存修改至数据库的。
- 使用QSqlRecord写入数据,相比较先插入一行,再写入数据等过程,简单很多。
- 一定要注意QSqlDatabase及QSqlTableModel的绑定。
- 创建QSqlDatabase时,注意QSqlDatabase(QSqlDatabase::addDatabase(“QSQLITE”,“test_database”));,最后面的"test_database"的内容,这是该数据库连接实例化的名称,不能重复。
- 可以使用QSqlTableModel的函数,也可以使用自定义的数据库语言操作。