数据库
Qt数据库编程
Qt SQL模块
1.在项目中使用Qt SQL模块
如果要在Qt项目中使用数据库编程功能,需要将Qt SQL模块添加到项目中,也就是需要在项目配置文件(.pro文件)中增加下面一条语句:
QT += sql
如果要在头文件或源程序文件中用到Qt SQL模块中的类,可以使用如下的包含语句;
plain
#include <Qtsql>
这样会将Qt SQL模块中常用的类包含进去。但是使用这条语句并不能包含Qt SQL模块中所有的类,例如,不能包含QDataWidgetMapper类。
2、Qt SQL支持的数据库
Qt SQL模块提供了一些常见数据库的驱动,驱动及对应数据库如表9-1所示。通过使用Qt sQL模块提供的功能,我们就可以编程实现对这些数据库的连接和操作。
3、Qt SQL模块中主要的类
Qt SOL模块提供了数据库编程所需的各种类,
| 类名 | 描述 |
|---|---|
| QSqlDatabase | 代表一个数据库连接。可以创建、打开、关闭和管理数据库连接。 |
| QSqlQuery | 提供了一个执行 SQL 查询的接口,支持查询、插入、更新和删除等操作。 |
| QSqlRecord | 表示从数据库查询中获取的单行数据。可用于获取字段名及其值。 |
| QSqlTableModel | 基于模型/视图架构的类,用于显示和编辑数据库表格数据。 |
| QSqlQueryModel | 只读模型类,用于显示从 SQL 查询获得的数据。 |
| QSqlError | 表示 SQL 操作的错误信息,提供错误码和描述。 |
| QSqlDriver | 负责与数据库驱动的基本交互,定义了数据库驱动的接口。 |
| QSqlField | 表示数据库表中的单个字段,包括字段名、值和属性信息。 |
| QSqlRelation | 用于表示数据库表之间的关系,通常在模型中使用以连接相关数据。 |
| QSqlQueryModel | 只读模型类,用于显示 SQL 查询结果。 |
示例:Qt的数据库模块(QSqlDatabase、QSqlQuery等)连接SQLite数据库
cpp
#include <QCoreApplication>
#include <QtSql>
#include <QDebug>
bool createConnection() {
// 1. 创建数据库连接
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("example.db");
if (!db.open()) {
qDebug() << "无法打开数据库:" << db.lastError().text();
return false;
}
return true;
}
void createTable() {
// 2. 使用QSqlQuery创建表
QSqlQuery query;
query.exec("CREATE TABLE IF NOT EXISTS person (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)");
}
void insertData() {
// 3. 插入数据
QSqlQuery query;
query.prepare("INSERT INTO person (name, age) VALUES (?, ?)");
query.addBindValue("张三");
query.addBindValue(30);
query.exec();
query.addBindValue("李四");
query.addBindValue(25);
query.exec();
}
void fetchData() {
// 4. 查询数据并使用QSqlRecord访问
QSqlQuery query("SELECT id, name, age FROM person");
while (query.next()) {
QSqlRecord record = query.record();
int id = record.value("id").toInt();
QString name = record.value("name").toString();
int age = record.value("age").toInt();
qDebug() << "ID:" << id << "Name:" << name << "Age:" << age;
}
}
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
if (createConnection()) {
createTable();
insertData();
fetchData();
}
return app.exec();
}
代码分析
- QSqlDatabase:用于创建和管理数据库连接。这段代码使用SQLite数据库,所以添加SQLite驱动。addDatabase("QSQLITE")指定使用SQLite。
- QSqlQuery:用于执行SQL语句,包括创建表、插入、查询等操作。
- QSqlRecord:用于从查询结果中检索单行数据,以字段名或索引访问值。
- 错误处理:通过lastError()获取错误信息并输出到调试窗口。
运行结果:
plain
ID: 1 Name: "张三" Age: 30
ID: 2 Name: "李四" Age: 25
数据库编程的模型/视图结构
基本原理
- 模型/视图结构:用于将数据与UI分离。模型表示数据,视图负责显示和编辑数据。
- 模型类与视图组件的结合:通过模型类(如 QSqlTableModel)将数据库中的数据映射到视图组件(如 QTableView)进行展示和操作。
Qt SQL模块中的主要模型类
QSqlQueryModel
- 用途:用于显示SQL查询结果。
- 特点:数据只读,不可编辑。
- 实现:仅支持 SELECT 语句,不支持 INSERT 或 UPDATE。
QSqlTableModel
- 用途:用于表示单个数据表。
- 特点:数据可编辑。
- 实现:支持 SELECT、INSERT、UPDATE 等SQL操作。
QSqlRelationalTableModel
- 用途:用于表示关系数据表。
- 特点:数据可编辑,支持将编码字段关联到另一表,实现直观的列表选择。
- 功能:通过关系将编码字段与编码表关联。
模型类的继承关系
- QAbstractItemModel 是基础抽象类。
- QAbstractTableModel 派生自 QAbstractItemModel,是表格模型的抽象基础类但不能用于实例化。
SQL语句和数据库操作
- 关系数据库:支持SQL,拥有强大的数据操作能力。
- QSqlTableModel的实现:通过内部支持多个SQL语句,来实现数据同步和更新。
- QSqlQueryModel的局限:由于仅使用 SELECT,无法更新数据到数据库。
常用几个数据库类
QSqlTableModel
QSqlTableModel 是 Qt SQL 模块中的一个重要类,主要用于在应用程序中方便地管理和操作数据库表的数据。它实现了模型/视图架构,特别适用于需要显示和编辑表格数据的场景。
主要特性
- 与数据库表直接关联:QSqlTableModel 直接映射到数据库中的表,简化了数据访问和更新。
- 支持增、删、改操作:可以轻松地插入、删除和更新记录,所有更改都会自动反映到数据库中。
- 可与 Qt 视图类集成:可以与 QTableView 等视图类结合使用,支持用户界面的快速构建。
- 模型支持:提供标准的模型接口,支持排序、过滤和用户自定义数据展示。
- 处理数据验证:在插入或更新操作时,可以进行数据验证,确保数据的一致性和完整性。
主要方法
- 构造函数与基本设置:
cpp
QSqlTableModel *model = new QSqlTableModel(parent);
model->setTable("tableName");
model->select(); // 加载数据
- 增、删、改操作:
cpp
// 插入新记录
model->insertRow(model->rowCount());
// 删除记录
model->removeRow(rowIndex);
// 更新数据
model->setData(model->index(rowIndex, columnIndex), newValue);
- 提交和撤销变更:
cpp
model->submitAll(); // 提交所有更改
model->revertAll(); // 撤销所有更改
- 排序与过滤:
cpp
model->setSort(columnIndex, Qt::AscendingOrder);
model->setFilter("columnName = 'value'"); // 设置过滤条件
示例:如何使用 QSqlTableModel 进行基本的数据库操作。
cpp
#include <QApplication>
#include <QSqlDatabase>
#include <QSqlTableModel>
#include <QTableView>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 连接到数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("example.db");
db.open();
// 创建模型
QSqlTableModel model(nullptr, db);
model.setTable("students");
model.select(); // 加载数据
// 配置视图
QTableView view;
view.setModel(&model);
view.setWindowTitle("Student Records");
view.show();
return app.exec();
}
QSqlQueryModel
QSqlQueryModel 是 Qt SQL 模块中的一个类,主要用于处理从 SQL 查询中获取的数据。与 QSqlTableModel 不同,QSqlQueryModel 适合只读操作,允许开发者从复杂的 SQL 查询中展示数据,而不需要直接映射到具体的数据库表。
主要特性
- 只读模型:QSqlQueryModel 仅用于显示数据,不能直接更改数据。适用于需要数据显示的场景。
- 自定义 SQL 查询:可使用自定义的 SQL 查询来填充模型,支持复杂的 JOIN 操作和过滤条件。
- 高效的数据展示:适合展示来自数据库的大量数据,提供快速的查询结果视图。
- 与视图类结合:可以与 QTableView、QListView 等视图类轻松集成,便于展现数据。
- 支持动态数据更新:在调用 setQuery() 方法后,模型可以动态更新数据。
主要方法
- 构造函数与查询设置:
cpp
QSqlQueryModel *model = new QSqlQueryModel(parent);
model->setQuery("SELECT * FROM tableName");
- 数据访问:
cpp
QVariant value = model->data(model->index(row, column));
- 动态更新查询:
cpp
model->setQuery("SELECT * FROM tableName WHERE condition");
- 排序:
cpp
model->setHeaderData(columnIndex, Qt::Horizontal, "Header Name"); // 设置表头
示例:如何使用 QSqlQueryModel 来显示查询结果
cpp
#include <QApplication>
#include <QSqlDatabase>
#include <QSqlQueryModel>
#include <QTableView>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 连接到数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("example.db");
db.open();
// 创建模型
QSqlQueryModel model;
model.setQuery("SELECT id, name FROM students");
// 配置视图
QTableView view;
view.setModel(&model);
view.setWindowTitle("Student Records");
view.show();
return app.exec();
}
QSqlQuery
QSqlQuery 是 Qt SQL 模块中的一个类,用于执行 SQL 语句并处理结果集。它提供了执行各种 SQL 操作(如查询、插入、更新和删除)的接口,并与数据库进行交互。
主要特性:
- 执行 SQL 语句:支持执行标准 SQL 语句,包括 SELECT、INSERT、UPDATE、DELETE 等。
- 处理结果集:可以检索和迭代查询结果,支持获取列数、行数和单个字段的值。
- 参数化查询:支持使用占位符以预防 SQL 注入,提升安全性。
- 事务支持:可以在事务中执行多个操作,确保数据的一致性。
- 高性能:优化了 SQL 操作的执行效率,特别是在处理大量数据时。
主要方法:
- 执行查询:
cpp
QSqlQuery query;
query.exec("SELECT * FROM tableName");
- 获取结果:
cpp
while (query.next()) {
QString name = query.value("name").toString();
int id = query.value(0).toInt();
}
- 参数化查询:
cpp
QSqlQuery query;
query.prepare("INSERT INTO students (name, age) VALUES (:name, :age)");
query.bindValue(":name", "Alice");
query.bindValue(":age", 20);
query.exec();
- 事务管理:
cpp
QSqlDatabase::database().transaction();
// 执行多个操作
QSqlDatabase::database().commit(); // 提交事务
示例:如何使用 QSqlQuery 进行数据库操作。
cpp
#include <QApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>
#include <QtSql>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 连接到数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("example.db");
if (!db.open()) {
qDebug() << "Database error occurred";
return -1;
}
// 执行查询
QSqlQuery query;
// 插入数据
query.prepare("INSERT INTO students (name, age) VALUES (:name, :age)");
query.bindValue(":name", "Alice");
query.bindValue(":age", 20);
if (!query.exec()) {
qDebug() << "Insert failed:" << query.lastError().text();
}
// 查询数据
query.exec("SELECT * FROM students");
while (query.next()) {
QString name = query.value("name").toString();
int age = query.value("age").toInt();
qDebug() << "Name:" << name << "Age:" << age;
}
return app.exec();
}
QSqlRelationalTableModel
QSqlRelationalTableModel 是 Qt SQL 模块中的一个类,扩展了 QSqlTableModel,适用于处理具有关系的多表数据。它允许使用外键在表之间建立关系,从而方便地管理和展示相关数据。
主要特性
- 关系模型支持:通过外键支持多个表之间的关系,简化了数据的展示和管理。
- 自动填充数据:可以根据外键自动填充关联表的数据,如将 ID 显示为相关联的名称。
- 编辑支持:允许用户直接在视图中编辑数据,自动管理数据的一致性。
- 方便的查询和过滤:支持对数据的查询、排序和过滤,能够高效处理复杂的数据结构。
主要方法
- 设置关系:
cpp
QSqlRelationalTableModel model;
model.setTable("students");
model.setRelation(2, QSqlRelation("classes", "class_id", "class_name"));
- 获取和设置数据:
cpp
model.select(); // 加载数据
QString className = model.data(model.index(row, classColumn)).toString();
- 插入和删除行:
cpp
model.insertRow(row);
model.removeRow(row);
- 保存更改:
cpp
model.submitAll(); // 提交所有修改
示例:如何使用 QSqlRelationalTableModel 来展示和编辑具有关系的数据。
cpp
#include <QApplication>
#include <QSqlDatabase>
#include <QSqlRelationalTableModel>
#include <QTableView>
#include <QDebug>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 连接到数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("example.db");
if (!db.open()) {
qDebug() << "Database connection error";
return -1;
}
// 创建模型
QSqlRelationalTableModel model;
model.setTable("students");
model.setRelation(2, QSqlRelation("classes", "class_id", "class_name")); // 设置外键关系
model.select(); // 获取数据
// 配置视图
QTableView view;
view.setModel(&model);
view.setWindowTitle("Student Records");
view.show();
return app.exec();
}