第六章 QT基础:9、Qt中数据库的操作

Qt数据库模块概述与使用详解

软件安装教程:https://subingwen.cn/qt/sql-driver/

1. 概述

Qt框架中对数据库操作提供了很好的支持,我们可以通过Qt提供的类非常方便地和本地或者远程数据库进行连接。

众所周知,数据库是 C-S(client-server)结构的,我们要连接的数据库属于服务器端,通过Qt编写的应用程序属于客户端。

如果想通过Qt访问数据库,首先我们需要在项目中添加数据库模块,模块名为 sql

找到项目文件 xxx.pro,把模块名加进去:

Cpp 复制代码
QT += core gui sql

💡 这个 sql 模块对应的是一个动态库,包含数据库相关类的二进制源码。使用时会被加载到内存中,按需提供服务。

Qt中常用的数据库相关类:

  • QSqlDatabase :添加/删除/复制/关闭数据库实例
  • QSqlQuery :数据库查询类
  • QSqlRecord :代表一行记录(表或视图中的一行)
  • QSqlField :代表一个字段(列)的信息
  • QSqlQueryModel :可用于视图展示的结果集接口
  • QSqlError :用于获取数据库操作失败的信息

!NOTE\] Qt中操作数据库的大致流程如下: 1. 创建数据库实例并初始化 2. 连接数据库 3. 执行增删查改等SQL语句 4. 关闭数据库


2. 类的使用

2.1 QSqlDatabase

QSqlDatabase 类提供了连接数据库的接口,一个实例表示一个连接。

常用静态函数
  • 获取支持的数据库驱动名列表:
cpp 复制代码
QStringList QSqlDatabase::drivers();

输出示例:

text 复制代码
("QSQLITE", "QMYSQL", "QMYSQL3", "QOCI", "QOCI8", "QODBC", "QODBC3", "QPSQL", "QPSQL7")

💡 有些驱动如 MySQL、Oracle 在高版本 Qt 中需要手动编译。

  • 添加数据库连接实例:
cpp 复制代码
QSqlDatabase QSqlDatabase::addDatabase(const QString &type, const QString &connectionName = QLatin1String("defaultConnection"));

参数说明:

  • type:数据库驱动名(如 "QMYSQL", "QOCI")
  • connectionName:连接名,默认是 "defaultConnection"
  • 通过连接名获取数据库实例:
cpp 复制代码
QSqlDatabase QSqlDatabase::database(const QString &connectionName = QLatin1String("defaultConnection"), bool open = true);
  • 判断连接是否存在:
cpp 复制代码
bool QSqlDatabase::contains(const QString &connectionName = QLatin1String("defaultConnection"));
常用成员函数
  • 设置连接参数:
cpp 复制代码
void setDatabaseName(const QString &name);
void setHostName(const QString &host);
void setPort(int port);
void setUserName(const QString &name);
void setPassword(const QString &password);
  • 连接和关闭数据库:
cpp 复制代码
bool open();        // 成功返回 true,失败返回 false
bool isOpen() const;
void close();
  • 获取错误信息:
cpp 复制代码
QSqlError lastError() const;
QString QSqlError::text() const;
事务控制:Qt 数据库模块(QSqlDatabase)中用于事务处理 的核心方法,目的是保证数据库操作的数据一致性与完整性
bool transaction();

🔹 作用:开启事务

  • 启动一个事务块,在事务块内进行的所有操作要么全部执行成功 ,要么全部不生效(可回滚)
  • 它告诉数据库:"从现在开始,我要执行一系列操作,这些操作要么全部成功、要么一个都不生效。
  • 适用于需要多步写操作的场景 ,比如插入多行数据、更新多个表等。
    🔸 使用场景示例:
cpp 复制代码
db.transaction();  // 开启事务

bool commit();

🔹 作用:提交事务->(让所有更改"落盘"保存)

  • 如果事务块中的所有 SQL 操作都成功,就使用 commit() 提交,表示这些操作将永久写入数据库
    🔸 使用场景示例:
cpp 复制代码
if (flag) {
    db.commit();  // 所有操作成功,提交事务
}

bool rollback();

🔹 作用:回滚事务 ->撤销自 transaction() 以来的所有更改

  • 如果事务中的任意操作失败 ,使用 rollback() 将数据库状态恢复到事务开始之前的样子。
  • 防止数据处于"部分成功"状态,保持一致性。
    🔸 使用场景示例:
cpp 复制代码
else {
    db.rollback();  // 有操作失败,全部撤销
}

2.2 QSqlQuery

QSqlQuery 封装了执行 SQL 查询的操作,支持 DML(如 INSERT)与 DDL(如 CREATE)语句。

构造函数:
cpp 复制代码
QSqlQuery(const QString &query = QString(), QSqlDatabase db = QSqlDatabase());

参数说明:

  • query:要执行的 SQL
  • db:数据库实例对象(可选)
执行 SQL:
cpp 复制代码
bool exec();                      // 执行构造时传入的 SQL
bool exec(const QString &query); // 执行指定 SQL
遍历结果集:
cpp 复制代码
bool next(); // 移动到下一条记录,成功返回 true
获取字段值:
cpp 复制代码
QVariant value(int index) const;
QVariant value(const QString &name) const;

💡 QVariant 是 Qt 中的通用类型包装器,需调用 .toString() .toInt() 等取出真实类型。


3. 示例代码(以 Oracle 数据库为例)

cpp 复制代码
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //获取本地支持的数据库驱动(建议首次使用时执行,便于确认可用驱动)
    // QSqlDatabase::drivers() 是一个静态函数,
    //返回当前Qt环境支持的数据库驱动名列表。
    QStringList ls = QSqlDatabase::drivers();
    qDebug() << ls; 
    // 示例输出: ("QSQLITE", "QMYSQL", "QOCI", ...)

    // 添加一个数据库连接实例
    // addDatabase("QOCI") 表示使用 Oracle 驱动创建一个数据库连接实例,默认连接名为 "defaultConnection"
    QSqlDatabase db = QSqlDatabase::addDatabase("QOCI");

    // 设置连接参数信息(包括主机名、端口、数据库名、用户名和密码)
    // 这些函数分别对应服务器连接的必要参数,必须在调用 open() 之前设置
    db.setHostName("110.22.80.130"); 
    // setHostName(): 设置数据库服务器主机IP
    db.setPort(1521);                
    // setPort(): 设置端口号,Oracle 默认端口为 1521
    db.setDatabaseName("orcl");      
    // setDatabaseName(): 设置数据库服务名或实例名
    db.setUserName("scott");         
    // setUserName(): 设置用户名
    db.setPassword("scott");         
    // setPassword(): 设置用户密码

    //尝试连接数据库,调用 open() 方法后根据返回值判断连接是否成功
    bool bl = db.open();             
    // open(): 尝试与数据库建立连接,成功返回 true
    if(!bl)
    {
        // lastError().text() 获取连接失败的错误描述信息
        qDebug() << db.lastError().text(); 
        // 打印错误信息
        return;
    }
    else
    {
        qDebug() << "数据库连接成功了...";
    }

    QSqlQuery query; 
    // 创建一个默认连接的查询对象
    
    //插入数据前开启事务,保障操作的原子性和一致性
    //transaction():启动一个事务,适用于写入类操作(insert/update/delete)
    QString sql = "insert into dept values(23, '火影忍者', '东京')";
    db.transaction(); 
    // 启动事务

    //执行插入语句
    bool flag = query.exec(sql); 
    // exec(sql): 执行 SQL 语句,成功返回 true
    if(flag)
    {
        db.commit(); 
        // commit(): 提交事务,将改动写入数据库
    }
    else
    {
        db.rollback(); 
        // rollback(): 回滚事务,恢复到事务开启前的状态
    }

    //执行 SELECT 查询,获取结果集
    query.exec("select dname, loc from dept");

    //通过 while 循环遍历结果集
    // next(): 将查询游标移动到下一行,成功返回 true
    while(query.next())
    {
        // value(int index): 根据字段索引获取字段值
        // value(QString name): 根据字段名获取字段值
        // toString(): 将 QVariant 类型转换为 QString 输出
        qDebug() << query.value(0).toString()         
        // 输出字段索引 0 的值(dname)
                 << query.value(1).toString()         
                 // 输出字段索引 1 的值(loc)
                 << query.value("dname").toString()   
                 // 输出字段名为 dname 的值
                 << query.value("loc").toString();    
                 // 输出字段名为 loc 的值
    }

    //关闭数据库连接,释放资源
    db.close(); // close(): 断开数据库连接,通常在程序结束或数据库操作完成后调用
}

数据库实例 = 运行中的数据库软件 + 占用的内存结构 + 后台进程,它让数据库"活着",能接受你连接、查询、存储数据。

!NOTE\] 想象你有一个图书馆系统软件(比如 Oracle 或 MySQL): * 📁 **数据库**:就是图书馆里的一堆书架(存储数据的结构) * ⚙️ **数据库实例**:就是图书管理员(负责接待查询、借书、维护的"运行中进程")

名称 含义 你在 Qt 中怎么用
数据库 存储结构(表、索引等) 用 SQL 操作(SELECT、INSERT)
实例 数据库运行时的进程和内存 setDatabaseName("orcl") 指定要连的 Oracle 实例
实际存数据的结构 SELECT * FROM dept

📚 作者:苏丙榅

🔗 来源:爱编程的大丙

📄 著作权归作者所有,非商业转载请注明出处。

相关推荐
hnlucky31 分钟前
Hadoop 单机模式(Standalone Mode)部署与 WordCount 测试
大数据·数据库·hadoop·分布式·缓存
shuair1 小时前
redis持久化-RDB
数据库·redis·bootstrap
唯♧1 小时前
使用 DBeaver 将数据从 PostgreSQL 导出到 SQLite
数据库·oracle
enyp801 小时前
Qt结构体运算符重载指南
开发语言·qt
我言秋日胜春朝★1 小时前
【MySQL】内置函数
数据库·mysql
编码小笨猪2 小时前
[ Qt ] | 第一个Qt程序
开发语言·qt
鸠。2 小时前
第四章 Maven
java·数据库·maven
极小狐2 小时前
如何创建并使用极狐GitLab 受保护标签?
数据库·ci/cd·gitlab·devops·mcp
脆皮瞎3 小时前
phpstorm用php连接数据库报错
数据库·php·phpstorm
没有感情的robot3 小时前
redis 有序集合zrange和zrangebyscore的区别
数据库·redis