【Qt】数据库实战(二)

00. 目录

01. 概述

SQL即结构化查询语言,是关系数据库的标准语言。前面已经在Qt里利用QSqlQuery类执行了SQL语句,这一节我们将详细讲解该类的使用。

02. 开发环境

Windows系统:Windows10

Qt版本:Qt5.15或者Qt6

03. 连接到数据库

3.1 新建Qt Widgets应用,项目名称为15SQL,基类为QMainWindow,类名为MainWindow。完成后打开15SQL.pro并添加代码:QT += sql 然后保存该文件。

3.2 向项目中添加新文件,模板选择C++分类中的C++ Header File,名称为connection.h,然后打开该文件,更改如下:

#ifndef CONNECTION_H
#define CONNECTION_H

#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>

static bool createConnection()
{
    //加载驱动
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(":memory:");

    bool ret = db.open();
    if (ret)
    {
        qDebug() << "连接到数据库成功";
    }
    else
    {
        qDebug() << "连接到数据库失败: " << db.lastError().text();
    }


    //创建QSqlQuery对象
    QSqlQuery query;
    query.exec("create table student(id int primary key, name varchar(20))");
    query.exec("insert into student values(1, 'first')");
    query.exec("insert into student values(2, 'second')");
    query.exec("insert into student values(3, 'third')");
    query.exec("insert into student values(4, 'fourth')");
    query.exec("insert into student values(5, 'fifth')");


    return true;
}

#endif // CONNECTION_H

头文件中我们添加了一个建立连接的函数,使用这个头文件的目的就是要简化主函数中的内容。这里先创建了一个SQLite数据库的默认连接,设置数据库名称时使用了“:memory:”,表明这个是建立在内存中的数据库,也就是说该数据库只在程序运行期间有效,等程序运行结束时就会将其销毁。当然,大家也可以将其改为一个具体的数据库名称,比如“my.db”,这样就会在项目目录中创建该数据库文件了。下面使用open()函数将数据库打开,如果打开失败,则弹出提示对话框。最后使用QSqlQuery创建了一个student表,并插入了包含id和name两个字段的五条记录,如下图所示。其中,id字段是int类型的,“primary key”表明该字段是主键,它不能为空,而且不能有重复的值;而name字段是varchar类型的,并且不大于20个字符。这里使用的SQL语句都要包含在双引号中,如果一行写不完,那么分行后,每一行都要使用两个双引号引起来。

3.3 main.cpp中调用连接函数。

#include "mainwindow.h"

#include <QApplication>
#include "connection.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    if (!createConnection())
    {
        return 1;
    }


    MainWindow w;
    w.show();
    return a.exec();
}

3.4 界面上添加一个按钮来实现查询操作。双击mainwindow.ui文件进入设计模式。然后将一个Push Button拖到界面上,并修改其显示文本为“查询”。效果如下图所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lCIAuh7Y-1616661582511)(assets/image-20210325161610312.png)]
在这里插入图片描述

3.5 在查询按钮上点击鼠标右键,选择“转到槽”,然后选择clicked()单击信号槽并点击OK,并实现对应的槽函数

//查询按钮
void MainWindow::on_pushButton_clicked()
{
    QSqlQuery query;

    query.exec("select * from student");

    while(query.next())
    {
        qDebug() << query.value(0).toInt()
                 << " " << query.value(1).toString();
    }
}

执行结果如下:

连接到数据库成功
1   "first"
2   "second"
3   "third"
4   "fourth"
5   "fifth"

04. 操作结果集

当query.exec(“select * from student”);这条语句执行完后,我们便获得了相应的执行结果,因为获得的结果可能不止一条记录,所以称之为结果集。结果集其实就是查询到的所有记录的集合,在QSqlQuery类中提供了多个函数来操作这个集合,需要注意这个集合中的记录是从0开始编号的。最常用的操作有:

seek(int n) :query指向结果集的第n条记录;
first() :query指向结果集的第一条记录;
last() :query指向结果集的最后一条记录;
next() :query指向下一条记录,每执行一次该函数,便指向相邻的下一条记录;
previous() :query指向上一条记录,每执行一次该函数,便指向相邻的上一条记录;
record() :获得现在指向的记录;
value(int n) :获得字段的值。其中n表示你查询的第n个字段,比如前面我们使用“select * from student”就相当于
“select id, name from student”,那么value(0)返回id字段的值,value(1)返回name字段的值。该函数返回
QVariant类型的数据,关于该类型与其他类型的对应关系,可以在帮助中查看QVariant。
at() :获得现在query指向的记录在结果集中的编号。

【提示】

刚执行完query.exec(“select * from student”);这行代码时,query是指向结果集以外的,我们可以利用query.next()使得query指向结果集的第一条记录。当然我们也可以利用seek(0)函数或者first()函数使query指向结果集的第一条记录。但是为了节省内存开销,推荐的方法是,在query.exec(“select * from student”);这行代码前加上query.setForwardOnly(true);这条代码,此后只能使用next()和seek()函数。

下面我们通过例子来演示一下这些函数的使用。将槽更改如下:

void MainWindow::on_pushButton_clicked()
{
    QSqlQuery query;

    query.exec("select * from student");
    qDebug() << "exec next()";

    //结果集指向第一条记录
    if (query.next())
    {
        //获取所指向的记录在结果集中的编号
        int rowNum = query.at();

        //获取每条记录中字段(列)的个数
        int columnNum = query.record().count();

        //获取name字段所在列的编号,列从左向右编号,最左边的编号为0
        int fieldNo = query.record().indexOf("name");

        //获取字段id的值
        int id = query.value(0).toInt();

        //获取name字段的值
        QString name = query.value(fieldNo).toString();

        //输出结果
        qDebug() << "rowNum: " << rowNum << " id: " << id
                 << " name: " << name << " columnNum: " << columnNum;


        qDebug() << "------------------------------";
        if (query.seek(2))
        {
            qDebug() << "rowNum: " << query.at()
                     << " id: " << query.value(0).toInt()
                     << " name: " << query.value(1).toString();
        }

        qDebug() << "------------------------------";
        if (query.last())
        {
            qDebug() << "rowNum: " << query.at()
                     << " id: " << query.value(0).toInt()
                     << " name: " << query.value(1).toString();
        }
    }

}

执行结果:

连接到数据库成功
exec next()
rowNum:  0  id:  1  name:  "first"  columnNum:  2
------------------------------
rowNum:  2  id:  3  name:  "third"
------------------------------
rowNum:  4  id:  5  name:  "fifth"

06. 附录

6.1 Qt教程汇总
网址:https://dengjin.blog.csdn.net/article/details/115174639

6.2 源码下载
网址:【Qt】数据库实战(二).rar

© 版权声明
THE END
喜欢就支持一下吧
点赞483 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容