重学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();
}
相关推荐
尘中远6 小时前
【Qwt 7.0 系列】坐标轴与刻度系统 —— 刻度引擎、网格、图例与刻度朝内
qt·数据可视化·qcustomplot·qwt·工业软件·科学绘图
sycmancia9 小时前
Qt——多线程间的互斥
开发语言·qt
尘中远14 小时前
【Qwt 7.0 系列】常用图表类型实战 —— 柱状图、散点图、箱线图与直方图
qt·qwt·工业软件·科学绘图
尘中远14 小时前
【Qwt 7.0 系列】交互功能详解 —— 平移、缩放、坐标轴交互与数据拾取
qt·数据可视化·绘图·qcustomplot·qwt·科学绘图
sycmancia14 小时前
Qt——进程与线程的概念
qt
郝学胜-神的一滴15 小时前
Qt 高级编程 034:深耕QWidget底层内核—彻底吃透无边框窗口设计核心原理
开发语言·c++·qt·程序人生·软件开发·用户界面
尘中远15 小时前
【Qwt 7.0 系列】3D 数据可视化 —— OpenGL 高性能三维绘图
qt·3d·qcustomplot·qwt·科学绘图·高性能绘图
满天星830357716 小时前
【Qt】控件(二) (geometry及与frameGeometry的区别)
开发语言·qt
大气的小蜜蜂16 小时前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·qt·sqlite
尘中远16 小时前
【Qwt 7.0 系列】总体架构解析 —— 从单体到三库模块化的演进
qt·matplotlib·绘图·qwt·科学绘图