Qt SQL 模块提供了跨平台的数据库访问功能,支持多种关系型数据库。以下是 Qt 6.0 中 SQL 模块的详细功能描述:
模块功能:
一、核心类及其功能
1. QSqlDatabase
功能:管理数据库连接
主要方法:
addDatabase()
: 添加数据库连接setDatabaseName()
: 设置数据库名称setHostName()
: 设置主机名setUserName()
/setPassword()
: 设置认证信息open()
/close()
: 打开/关闭连接tables()
: 获取所有表名primaryIndex()
: 获取表的主键索引
特性:
支持连接池管理
提供事务支持(commit/rollback)
2. QSqlQuery
功能:执行SQL语句并处理结果
主要方法:
exec()
: 执行SQL语句prepare()
: 准备SQL语句bindValue()
: 绑定参数值next()
: 遍历结果集value()
: 获取当前记录字段值lastInsertId()
: 获取最后插入的ID
特性:
支持预处理语句(防止SQL注入)
支持批量执行模式
提供执行状态检查(lastError/isActive)
3. 数据模型类
QSqlQueryModel
只读数据模型,适合显示查询结果
轻量级,不缓存数据
可通过
setQuery()
更新数据
QSqlTableModel
可编辑的单表数据模型
主要方法:
setTable()
: 设置操作的表select()
: 执行查询setEditStrategy()
: 设置编辑策略insertRecord()
/removeRow()
: 增删记录
特性:
支持三种编辑策略:
OnFieldChange: 即时提交
OnRowChange: 行变更时提交
OnManualSubmit: 手动提交
QSqlRelationalTableModel
扩展QSqlTableModel,支持外键关系
特殊方法:
setRelation()
: 设置字段关系relationModel()
: 获取关联模型
特性:
自动处理外键显示
支持关联表编辑
二、Qt 6.0 中的新特性和变化
1. 模块结构调整
核心功能在QtSql模块
数据库驱动分为独立模块:
QtSqlite (内置)
QtMysql (需单独安装)
QtPostgresql (需单独安装)
其他驱动类似
2. API改进
移除了废弃的API:
不再支持QSqlResult::handle()
清理了过时的绑定方法
增强了类型安全性:
更严格的参数类型检查
改进的枚举类型
3. 功能增强
批量操作优化:
改进的批处理执行性能
更高效的缓存管理
预处理语句:
支持命名参数绑定
更好的参数类型推断
事务处理:
更可靠的事务管理
支持保存点(savepoint)
4. 驱动层改进
SQLite驱动默认包含在Qt核心中
各驱动支持的新特性:
MySQL: 更好的SSL连接支持
PostgreSQL: 扩展类型支持
ODBC: 改进的Unicode处理
三、数据库支持详情
1. SQLite
无需服务器,零配置
完全支持事务
内置在Qt中,无需额外安装
限制:不支持某些高级SQL特性
2. MySQL/MariaDB
需要安装QtMysql模块
支持的特性:
预处理语句
SSL加密连接
大字段(BLOB)处理
要求:客户端库必须可用
3. PostgreSQL
需要安装QtPostgresql模块
支持的特性:
通知/监听机制
数组类型
大对象处理
要求:libpq库必须可用
4. ODBC
跨数据库的统一接口
支持的特性:
连接池
参数绑定
常用于连接SQL Server等商业数据库
四、典型使用模式
1. 基本查询流程
// 1. 创建连接
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("testdb");
db.setUserName("user");
db.setPassword("pass");
if (!db.open()) {
qDebug() << "Error:" << db.lastError().text();
return;
}
// 2. 执行查询
QSqlQuery query;
query.prepare("SELECT name, salary FROM employees WHERE dept = ?");
query.addBindValue("Engineering");
if (!query.exec()) {
qDebug() << "Query error:" << query.lastError().text();
return;
}
// 3. 处理结果
while (query.next()) {
QString name = query.value("name").toString();
double salary = query.value("salary").toDouble();
qDebug() << name << "earns" << salary;
}
2. 使用表模型
// 1. 创建模型
QSqlTableModel model;
model.setTable("employees");
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
model.select();
// 2. 显示数据
QTableView view;
view.setModel(&model);
view.show();
// 3. 修改数据
model.setData(model.index(0, 1), "New Name");
model.submitAll();
3. 事务处理
QSqlDatabase::database().transaction();
QSqlQuery query;
query.exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
query.exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
if (/* 检查错误 */) {
QSqlDatabase::database().rollback();
qDebug() << "Transaction rolled back";
} else {
QSqlDatabase::database().commit();
qDebug() << "Transaction committed";
}
五、最佳实践和注意事项
连接管理:
及时关闭不再使用的连接
合理使用连接池
性能优化:
使用预处理语句减少解析开销
对批量操作使用事务
合理设置模型缓存大小
错误处理:
始终检查数据库操作返回值
使用lastError()获取详细错误信息
线程安全:
连接不能在线程间共享
每个线程需要自己的数据库连接
SQL注入防护:
始终使用参数绑定而非字符串拼接
使用QSqlQuery::prepare()预处理语句
Qt 6.0的SQL模块在保持向后兼容的同时,提供了更清晰的结构和更好的性能,是开发数据库应用的强大工具。
架构解析
一、整体架构层次
Qt SQL 模块采用典型的三层架构:
+-----------------------+
| 应用程序层 |
| (使用Qt SQL API) |
+-----------------------+
↓
+-----------------------+
| SQL API抽象层 |
| (QSqlDatabase等核心类)|
+-----------------------+
↓
+-----------------------+
| 驱动层 |
| (数据库特定实现) |
+-----------------------+
↓
+-----------------------+
| 原生数据库客户端库 |
+-----------------------+
二、核心组件及其交互
1. 应用程序接口层
主要类:
QSqlDatabase:数据库连接管理
QSqlQuery:SQL查询执行
QSqlTableModel/QSqlRelationalTableModel:数据模型
QSqlError:错误处理
职责:
提供统一的数据库访问API
管理数据库连接
执行SQL操作
数据模型与视图的集成
2. 驱动管理层
核心类:
QSqlDriver:抽象驱动接口
QSqlDriverCreator:驱动创建模板
QSqlResult:抽象查询结果
职责:
加载和管理数据库驱动
提供驱动插件接口
处理驱动与核心API的交互
3. 驱动实现层
组成:
SQLite驱动 (内置)
MySQL驱动 (qt-sql-mysql)
PostgreSQL驱动 (qt-sql-psql)
ODBC驱动 (qt-sql-odbc)
其他第三方驱动
架构特点:
每个驱动实现QSqlDriver接口
驱动通常包装原生客户端库
以插件形式动态加载
三、关键架构设计
1. 驱动插件机制
工作流程:
应用程序调用QSqlDatabase::addDatabase()
驱动管理器查找注册的驱动工厂
驱动工厂创建具体的QSqlDriver实例
返回驱动给应用程序使用
优势:
支持动态加载不同数据库驱动
易于扩展新的数据库支持
减少核心模块体积
2. 连接池实现
架构要点:
由QSqlDatabase静态方法管理
每个连接由连接名标识
线程安全的连接管理
典型流程:
// 主线程创建连接
QSqlDatabase::addDatabase("QSQLITE", "conn1");
// 工作线程获取连接
QSqlDatabase db = QSqlDatabase::database("conn1");
3. 查询执行流程
查询准备阶段:
QSqlQuery::prepare()生成QSqlResult
驱动创建原生预处理语句
参数绑定阶段:
值通过QVariant系统传递
驱动处理类型转换
执行阶段:
驱动执行原生查询
返回结果集游标
结果获取阶段:
通过QSqlResult逐行获取数据
数据转换为QVariant
四、线程模型架构
1. 连接线程规则
不可共享原则:连接不能在线程间共享
线程局部存储:每个线程维护自己的连接列表
驱动线程安全要求:驱动必须实现threadSafe()方法
2. 多线程支持模式
模式1:每线程独立连接
// 工作线程中
void Worker::run() {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
// 使用独立连接
}
模式2:连接池共享
// 主线程
QSqlDatabase::addDatabase("QPSQL", "pooled_conn");
// 工作线程
QSqlDatabase db = QSqlDatabase::database("pooled_conn");
五、数据模型架构
1. 模型-视图集成
+------------+ +----------------+ +-----------+
| View | ←→ | SQL Model | ←→ | Database |
+------------+ +----------------+ +-----------+
2. 模型层级结构
QSqlQueryModel:基础只读模型
直接执行SQL查询
最小化内存使用
QSqlTableModel:可编辑单表模型
自动生成SELECT/INSERT/UPDATE语句
支持三种提交策略
QSqlRelationalTableModel:关系型模型
扩展QSqlTableModel
内置外键关系处理
自动JOIN查询
六、Qt 6.0架构改进
1. 模块化重构
核心模块 (QtSql):基础API
驱动模块 (qt-sql-*):数据库特定实现
影响:
减少默认打包体积
更清晰的依赖关系
简化驱动更新流程
2. 类型系统集成
深度集成QVariant类型系统
改进的类型安全机制:
强类型参数绑定
更精确的错误报告
自动类型转换优化
3. 性能优化架构
批处理执行管道:
减少驱动往返次数
批量参数绑定
缓存改进:
智能结果集缓存
按需数据加载
七、典型场景架构分析
1. 数据库初始化流程
2. 查询执行流程
八、扩展架构
1. 自定义驱动开发
实现步骤:
继承QSqlDriver
实现纯虚方法:
createResult()
hasFeature()
open()/close()
实现QSqlResult派生类
注册驱动工厂
示例架构:
CustomDriver
├── CustomResult
├── 实现原生API封装
└── 注册QT_PLUGIN_METADATA
2. 代理驱动模式
应用场景:
数据库访问监控
SQL重写
连接池增强
架构设计:
ProxyDriver
├── 包装实际驱动
├── 拦截方法调用
└── 添加额外处理
Qt 6.0 SQL模块的架构设计体现了良好的扩展性和灵活性,通过清晰的层次划分和插件机制,既保证了核心API的稳定性,又支持多样化的数据库访问需求。