重学Qt——数据库

数据库

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();
}

代码分析

  1. QSqlDatabase:用于创建和管理数据库连接。这段代码使用SQLite数据库,所以添加SQLite驱动。addDatabase("QSQLITE")指定使用SQLite。
  2. QSqlQuery:用于执行SQL语句,包括创建表、插入、查询等操作。
  3. QSqlRecord:用于从查询结果中检索单行数据,以字段名或索引访问值。
  4. 错误处理:通过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 模块中的一个重要类,主要用于在应用程序中方便地管理和操作数据库表的数据。它实现了模型/视图架构,特别适用于需要显示和编辑表格数据的场景。

主要特性

  1. 与数据库表直接关联:QSqlTableModel 直接映射到数据库中的表,简化了数据访问和更新。
  2. 支持增、删、改操作:可以轻松地插入、删除和更新记录,所有更改都会自动反映到数据库中。
  3. 可与 Qt 视图类集成:可以与 QTableView 等视图类结合使用,支持用户界面的快速构建。
  4. 模型支持:提供标准的模型接口,支持排序、过滤和用户自定义数据展示。
  5. 处理数据验证:在插入或更新操作时,可以进行数据验证,确保数据的一致性和完整性。

主要方法

  • 构造函数与基本设置:
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,适用于处理具有关系的多表数据。它允许使用外键在表之间建立关系,从而方便地管理和展示相关数据。

主要特性

  1. 关系模型支持:通过外键支持多个表之间的关系,简化了数据的展示和管理。
  2. 自动填充数据:可以根据外键自动填充关联表的数据,如将 ID 显示为相关联的名称。
  3. 编辑支持:允许用户直接在视图中编辑数据,自动管理数据的一致性。
  4. 方便的查询和过滤:支持对数据的查询、排序和过滤,能够高效处理复杂的数据结构。

主要方法

  • 设置关系:
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();
}
相关推荐
sycmancia9 小时前
Qt——发送自定义事件
开发语言·qt
ai安歌11 小时前
鸿蒙PC:Qt适配OpenHarmony实战【人名录】:单机联系人卡片,不读系统通讯录也能演示详情联动
数据库·qt·harmonyos
丁劲犇11 小时前
使用TraeAI开发Web页面测试MSYS2 ucrt64 Qt MCP服务器
服务器·前端·c++·qt·mcp
CodeKwang11 小时前
Qt6.5数控加工CAM框架实战:基于工厂模式与分层架构的CamCore完整实现
qt·框架·工业软件·cam
我在人间贩卖青春12 小时前
重学Qt——自定义库
qt
小燚~12 小时前
MSVCR100.dII报错问题处理
c++·windows·qt
lqj_本人12 小时前
鸿蒙PC:Qt适配OpenHarmony实战【花账】:从一笔支出开始,做一个本地记账小应用
数据库·qt·harmonyos
我在人间贩卖青春13 小时前
重学Qt——文件系统和文件读写
qt
sycmancia13 小时前
Qt——发送自定义事件(下)
开发语言·qt