数据库查询工具开发学习笔记
一、项目背景与目标
背景:频繁编写数据库查询语句,希望通过工具简化操作,提升效率。
二、总体设计思路
1. 架构设计
MVC模式:通过Qt控件实现视图(UI),业务逻辑(数据库操作、查询处理)封装在dataQueryImpl
类中,使用QSqlQueryModel
作为数据模型显示查询结果。模块化设计:分离数据库连接管理、UI初始化、查询逻辑、历史记录等功能,便于维护和扩展。
2. 核心功能模块
- 数据库连接管理:支持动态切换数据库路径,处理连接创建、关闭、错误处理。
- 可视化UI :通过
QSplitter
分隔左右区域,左侧显示表和列结构,右侧输入查询条件并展示结果。 - 查询功能:支持自由SQL输入和可视化条件拼接(通过列选择、运算符下拉框、值输入)。
- 查询历史 :记录最近50条查询语句,便于快速复用。
三、核心代码解析
1. 数据库连接与切换(核心逻辑)
cpp
void dataQueryImpl::setDB(const QString& dbPath) {
// 1. 关闭旧连接
if (db.isOpen()) db.close();
// 2. 移除旧默认连接(避免重复)
QSqlDatabase::removeDatabase("");
// 3. 创建新连接
db = QSqlDatabase::addDatabase("QSQLITE", "");
db.setDatabaseName(dbPath);
// 4. 打开数据库并处理错误
if (!db.open()) {
qCritical() << "数据库打开失败:" << db.lastError().text();
} else {
qDebug() << "数据库路径已更新为:" << dbPath;
updateUI(); // 刷新表列表
}
}
- 设计要点 :显式管理数据库连接,避免内存泄漏;切换数据库后自动刷新表列表(
updateUI
)。
3. 查询逻辑与结果展示
cpp
QSqlQueryModel* dataQueryImpl::queryData(const QString& query) {
QSqlQueryModel* newModel = new QSqlQueryModel();
newModel->setQuery(query, db); // 指定数据库连接
if (newModel->lastError().isValid()) {
qDebug() << "Query error:" << newModel->lastError().text();
}
appendQueryHistory(query); // 记录查询历史
return newModel;
}
void dataQueryImpl::onExecuteQueryButtonClicked() {
QString query = queryInput->text();
QSqlQueryModel* newModel = queryData(query);
tableView->setModel(newModel);
// 释放旧模型内存
if (model != newModel) delete model;
model = newModel;
}
- 关键逻辑 :使用
QSqlQueryModel
直接绑定数据库查询结果到表格;查询前记录历史,支持最多50条记录的循环存储。
4. 条件查询与可视化拼接
cpp
void dataQueryImpl::onAddConditionButtonClicked() {
QString column = columnListView->currentIndex().data().toString();
QString sqlOp = conditionOperatorComboBox->currentData().toString();
QString value = valueInput->text().trimmed();
// 格式化值(处理引号、LIKE通配符等)
QString formattedValue = valueFormatters[sqlOp].arg(value);
QString condition = column + " " + sqlOp + " " + formattedValue;
// 拼接多个条件(使用AND连接)
conditionsInput->setText(conditionsInput->text().isEmpty() ?
condition : conditionsInput->text() + " AND " + condition);
}
QSqlQueryModel* dataQueryImpl::queryDataByConditions(const QString& tableName, const QMap<QString, QString>& conditions) {
QString query = "SELECT * FROM " + tableName;
if (!conditions.isEmpty()) {
query += " WHERE " + conditions.keys().join(" = :") + " = :"; // 简化条件拼接
}
return queryData(query);
}
onditions.keys().join(" = :") + " = :"; // 简化条件拼接
}
return queryData(query);
}