QSqlTableModel 是 Qt 框架中提供的一个高级数据库模型类,它继承自 QSqlQueryModel,专门用于处理单个数据库表的读写操作。它封装了许多数据库操作的细节,使得开发者可以更方便地与数据库表进行交互。
一、核心特性
-
单表操作:专门针对数据库中的一个表进行操作
-
可编辑性:支持对数据的修改、添加和删除
-
自动生成SQL:自动生成SELECT、INSERT、UPDATE和DELETE语句
-
视图集成:可以直接与QTableView等视图组件绑定
二、基本使用示例
#include <QSqlDatabase>
#include <QSqlTableModel>
#include <QTableView>
// 创建数据库连接
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("example.db");
if (!db.open()) {
qDebug() << "无法打开数据库";
return;
}
// 创建模型
QSqlTableModel *model = new QSqlTableModel;
model->setTable("employees"); // 设置要操作的表
model->setEditStrategy(QSqlTableModel::OnManualSubmit); // 设置编辑策略
model->select(); // 从数据库加载数据
// 创建视图并设置模型
QTableView *view = new QTableView;
view->setModel(model);
view->show();
三、主要功能详解
1. 编辑策略 (EditStrategy)
QSqlTableModel 提供了三种编辑策略:
enum EditStrategy {
OnFieldChange, // 字段变化时立即提交
OnRowChange, // 行变化时提交
OnManualSubmit // 手动提交
};
//示例
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
// 修改数据
model->setData(model->index(0, 1), "张三");
// 手动提交更改
if (!model->submitAll()) {
qDebug() << "提交失败:" << model->lastError().text();
}
// 或者回滚更改
model->revertAll();
2. 数据筛选和排序
// 设置筛选条件 (相当于SQL的WHERE子句)
model->setFilter("salary > 5000 AND department = 'IT'");
// 设置排序 (相当于SQL的ORDER BY子句)
model->setSort(2, Qt::AscendingOrder); // 按第2列升序排序
// 重新加载数据
model->select();
3. 添加和删除记录
// 添加新记录
QSqlRecord record = model->record();
record.setValue("name", "李四");
record.setValue("salary", 8000);
model->insertRecord(-1, record); // -1表示追加到最后
// 删除当前行
model->removeRow(currentRow);
// 提交更改
model->submitAll();
4. 表头自定义
// 设置水平表头标签
model->setHeaderData(0, Qt::Horizontal, tr("ID"));
model->setHeaderData(1, Qt::Horizontal, tr("姓名"));
model->setHeaderData(2, Qt::Horizontal, tr("工资"));
四、实际应用场景示例
1. 员工管理系统
假设我们有一个员工表(employees)包含以下字段:id, name, department, salary。
// 初始化模型
QSqlTableModel *employeeModel = new QSqlTableModel(this);
employeeModel->setTable("employees");
employeeModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
// 设置友好的表头
employeeModel->setHeaderData(0, Qt::Horizontal, tr("工号"));
employeeModel->setHeaderData(1, Qt::Horizontal, tr("姓名"));
employeeModel->setHeaderData(2, Qt::Horizontal, tr("部门"));
employeeModel->setHeaderData(3, Qt::Horizontal, tr("薪资"));
// 只显示IT部门的员工
employeeModel->setFilter("department = 'IT'");
employeeModel->select();
// 绑定到视图
ui->tableView->setModel(employeeModel);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
2. 添加新员工
// 获取空记录
QSqlRecord newRecord = employeeModel->record();
// 设置字段值
newRecord.setValue("name", "王五");
newRecord.setValue("department", "HR");
newRecord.setValue("salary", 6500);
// 插入记录
if (employeeModel->insertRecord(-1, newRecord)) {
if (employeeModel->submitAll()) {
QMessageBox::information(this, "成功", "员工添加成功");
} else {
QMessageBox::warning(this, "错误", "提交失败: " + employeeModel->lastError().text());
}
}
五、性能优化技巧
1. 按需获取字段:只选择需要的列
model->setTable("employees");
model->select(); // 默认获取所有列
// 优化:只获取需要的列
QStringList columns = {"name", "department"};
QString query = "SELECT " + columns.join(",") + " FROM employees";
model->setQuery(query);
2. 批量操作:对于大量数据操作,使用事务
db.transaction();
// 执行多个操作...
if (!db.commit()) {
db.rollback();
}
3. 合理使用编辑策略:大数据量时使用OnManualSubmit
六、常见问题解决
数据不刷新:
model->select(); // 重新查询数据
提交失败:
if (!model->submitAll()) {
qDebug() << "错误:" << model->lastError().text();
}
主键问题:
-
确保表有主键,否则某些操作会失败
-
可以调用
model->setPrimaryKey()
设置主键
总结
QSqlTableModel 是Qt中一个非常方便的数据库操作类,它特别适合:
-
需要对单个表进行CRUD操作的场景
-
快速开发数据库管理界面
-
需要将数据库表直接绑定到视图组件的应用
它的主要优点是简化了数据库操作,但灵活性相对较低。对于复杂的SQL查询或需要跨表操作的情况,可能需要使用QSqlQuery或QSqlQueryModel。