1. QSqlQuery 核心功能解析
QSqlQuery 是 Qt SQL 模块中最基础也最强大的数据库操作类,它提供了直接执行任意 SQL 语句的能力。与 QSqlTableModel 和 QSqlQueryModel 这类高级封装不同,QSqlQuery 更适合需要精细控制 SQL 操作的场景。
1.1 基础操作模式
QSqlQuery 支持两种基本使用方式:
cpp复制// 方式一:直接执行SQL语句
QSqlQuery query;
query.exec("SELECT * FROM employee");
// 方式二:预处理语句(推荐)
QSqlQuery query;
query.prepare("INSERT INTO employee (name, age) VALUES (?, ?)");
query.addBindValue("张三");
query.addBindValue(25);
query.exec();
预处理语句的优势在于:
- 防止 SQL 注入攻击
- 提高重复执行相同语句的性能
- 更清晰的参数绑定机制
1.2 参数绑定方式详解
QSqlQuery 提供三种参数绑定方式:
- 位置参数(问号占位符):
cpp复制query.prepare("UPDATE employee SET dept=?, salary=? WHERE id=?");
query.addBindValue("技术部");
query.addBindValue(8000);
query.addBindValue(1001);
- 命名参数(冒号前缀):
cpp复制query.prepare("SELECT * FROM employee WHERE dept=:dept AND salary>:salary");
query.bindValue(":dept", "市场部");
query.bindValue(":salary", 5000);
- 序号绑定(混合使用):
cpp复制query.prepare("CALL sp_employee_update(?, :salary)");
query.bindValue(0, 1001);
query.bindValue(":salary", 7500);
提示:对于需要多次执行的相同语句,预处理后只需改变绑定值即可重复执行,这在批量操作时能显著提升性能。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 记录集操作实战技巧
2.1 遍历查询结果
当执行 SELECT 语句后,可以通过以下方式遍历结果集:
cpp复制QSqlQuery query("SELECT id, name FROM employee");
while (query.next()) {
int id = query.value(0).toInt(); // 按列索引获取
QString name = query.value("name").toString(); // 按列名获取
qDebug() << id << name;
}
关键导航方法:
first()/last():移动到首/末记录next()/previous():前后移动seek(index):定位到指定位置
2.2 大数据集优化
处理大量数据时需要注意:
cpp复制QSqlQuery query;
query.setForwardOnly(true); // 设置为仅向前遍历
query.exec("SELECT * FROM large_table");
while (query.next()) {
// 处理数据...
}
设置 setForwardOnly(true) 可以:
- 减少内存占用
- 提高查询速度
- 但会失去双向遍历能力
3. 事务处理与错误控制
3.1 事务管理示例
cpp复制QSqlDatabase::database().transaction(); // 开始事务
QSqlQuery query;
query.prepare("UPDATE account SET balance=balance-? WHERE id=?");
query.addBindValue(amount);
query.addBindValue(fromId);
if (!query.exec()) {
QSqlDatabase::database().rollback();
return false;
}
// 更多操作...
QSqlDatabase::database().commit(); // 提交事务
3.2 错误处理最佳实践
cpp复制QSqlQuery query;
if (!query.exec("SELECT * FROM non_existent_table")) {
QSqlError error = query.lastError();
qDebug() << "
