【Qt】数据库实战(三)

00. 目录

01. 概述

Qt数据库模型中提供名字绑定和位置绑定。

02. 开发环境

Windows系统:Windows10

Qt版本:Qt5.15或者Qt6

03. 增删改查操作

3.1 数据库查询参考代码

//数据库查询
QSqlQuery query;
query.exec("select * from dept");

while (query.next()) {
    //value(0) 表示第一个字段
    int id = query.value(0).toInt();
    QString name = query.value(1).toString();
    QString loc = query.value(2).toString();

    qDebug() << id << " " << name << " " << loc;
}

3.2 数据库删除参考代码

//删除
QSqlQuery query;
query.exec("delete from dept where id = 1");

3.3 数据库更新参考代码

//更新
QSqlQuery query;
query.exec("UPDATE dept SET name = 'name' WHERE id = 3");

3.4 数据库插入参考代码

//插入
QSqlQuery query;
query.exec("INSERT INTO dept (id, name, loc) "
           "VALUES (1, '1name', '1loc')");

【注意】 如果构造QSqlQuery的时候 指定了执行的语句, 那么不需要调用exec函数执行

错误代码如下:

//如果这样去构造一个对象 那么将会自动执行 不需要调用exec
QSqlQuery query("insert into dept(id, name, loc) values(4, '4name', '4loc')");
if (query.exec())
{
    qDebug() << "insert into database ok";
}
else
{
    qDebug() << "insert into database faield...";
}

04. 名字绑定和位置绑定

4.1 名字绑定方式一

//名字绑定  Oracle风格
QSqlQuery query;
query.prepare("INSERT INTO dept (id, name, loc) "
              "VALUES (:id, :name, :loc)");
//通过名字绑定值
query.bindValue(":id", 5);
query.bindValue(":name", "5name");
query.bindValue(":loc", "5loc");
//执行
ok = query.exec();

4.2 名字绑定方式二

//名字占位符 位置绑定
QSqlQuery query;
query.prepare("INSERT INTO dept (id, name, loc) "
              "VALUES (:id, :name, :loc)");
query.bindValue(0, 6);
query.bindValue(1, "6name");
query.bindValue(2, "6loc");
ok = query.exec();

4.3 名字绑定方式三

//名字占位符 位置绑定
QSqlQuery query;
query.prepare("INSERT INTO dept (id, name, loc) "
              "VALUES (:id, :name, :loc)");
//按照次序进行绑定
query.addBindValue(7);
query.addBindValue("7name");
query.addBindValue("7loc");
ok = query.exec();

4.4 位置绑定方式一

//位置绑定  MySQL风格
QSqlQuery query;
query.prepare("INSERT INTO dept (id, name, loc) "
              "VALUES (?, ?, ?)");
query.bindValue(0, 8);
query.bindValue(1, "8name");
query.bindValue(2, "8loc");
query.exec();

4.5 位置绑定方式二

//位置绑定  MySQL风格
QSqlQuery query;
query.prepare("INSERT INTO dept (id, name, loc) "
              "VALUES (?, ?, ?)");
query.addBindValue(9);
query.addBindValue("9name");
query.addBindValue("9loc");
query.exec();

05. 程序示例

5.1 首先在设计模式往界面上添加一个Spin Box部件,如下图所示。
在这里插入图片描述

5.2 将查询按钮槽里面的内容更改如下:

void MainWindow::on_pushButton_clicked()
{
    QSqlQuery query;

    int id = ui->spinBox->value();

    query.exec(QString("select name from student where id = %1").arg(id));

    //指向第一个有效数据
    query.next();

    QString name = query.value(0).toString();

    qDebug() << name;
}

这里使用了QString类的arg()函数实现了在SQL语句中使用变量,我们运行程序,更改Spin Box的值,然后点击查询按钮,效果如下图所示。

连接到数据库成功
"first"
"second"

5.3 在QSqlQuery类中提供了数据绑定同样可以实现在SQL语句中使用变量,虽然它也是通过占位符来实现的,不过使用它形式上更明了一些。下面先来看一个例子,将查询按钮槽更改如下:

void MainWindow::on_pushButton_clicked()
{
    QSqlQuery query;

    query.prepare("insert into student(id, name) "
                  "values(:id, :name)");
    query.bindValue(0, 6);
    query.bindValue(1, "sixth");

    query.exec();

    //执行查询操作
    query.exec("select * from student");
    query.last();
    int id = query.value(0).toInt();
    QString name = query.value(1).toString();
    qDebug() << "id: " << id << " name: " << name;
}

执行结果:

连接到数据库成功
id:  6  name:  "sixth"

这里在student表的最后又添加了一条记录。然后我们先使用了prepare()函数,在其中利用了“:id”和“:name”来代替具体的数据,而后又利用bindValue()函数给id和name两个字段赋值,这称为绑定操作。其中编号0和1分别代表“:id”和“:name”,就是说按照prepare()函数中出现的字段从左到右编号,最左边是0 。

5.4 位置绑定

void MainWindow::on_pushButton_clicked()
{
    QSqlQuery query;

    query.prepare("insert into student(id, name) "
                  "values(?, ?)");
    query.bindValue(0, 6);
    query.bindValue(1, "sixth");

    query.exec();

    //执行查询操作
    query.exec("select * from student");
    query.last();
    int id = query.value(0).toInt();
    QString name = query.value(1).toString();
    qDebug() << "id: " << id << " name: " << name;
}

也可以利用addBindValue()函数,这样就可以省去编号,它是按顺序给字段赋值的,如下:

void MainWindow::on_pushButton_clicked()
{
    QSqlQuery query;

    query.prepare("insert into student(id, name) "
                  "values(?, ?)");
    query.addBindValue(6);
    query.addBindValue("sixth");

    query.exec();

    //执行查询操作
    query.exec("select * from student");
    query.last();
    int id = query.value(0).toInt();
    QString name = query.value(1).toString();
    qDebug() << "id: " << id << " name: " << name;
}

当用ODBC的表示方法时,我们也可以将编号用实际的占位符代替,如下:

void MainWindow::on_pushButton_clicked()
{
    QSqlQuery query;

    query.prepare("insert into student(id, name) "
                  "values(:id, :name)");
    query.bindValue(":id", 6);
    query.bindValue(":name", "sixth");

    query.exec();

    //执行查询操作
    query.exec("select * from student");
    query.last();
    int id = query.value(0).toInt();
    QString name = query.value(1).toString();
    qDebug() << "id: " << id << " name: " << name;
}

5.5 通过绑定操作在SQL语句中使用变量。更改槽函数如下:

void MainWindow::on_pushButton_clicked()
{
    QSqlQuery query;

    query.prepare("select name from student where id = ?");
    int id = ui->spinBox->value();

    query.addBindValue(id);

    query.exec();

    query.next();
    qDebug() << query.value(0).toString();
}

执行结果

连接到数据库成功
"third"

06. 批处理操作

当要进行多条记录的操作时,我们就可以利用绑定进行批处理。将槽更改如下:


void MainWindow::on_pushButton_clicked()
{
    QSqlQuery query;

    query.prepare("insert into student values(?, ?)");
    QVariantList ints;
    ints << 10 << 11 << 12 << 13;
    query.addBindValue(ints);

    QVariantList names;
    names << "xiaoming" << "xiaogang" << "xiaohua" << QVariant(QVariant::String);
    query.addBindValue(names);

    if (!query.execBatch())
    {
        qDebug() << query.lastError().text();
    }

    //输出整张表
    query.exec("select * from student");
    while(query.next())
    {
        int id = query.value(0).toInt();
        QString name = query.value(1).toString();

        qDebug() << id << " " << name;
    }

}

执行结果:

连接到数据库成功
1   "first"
2   "second"
3   "third"
4   "fourth"
5   "fifth"
10   "xiaoming"
11   "xiaogang"
12   "xiaohua"
13   ""

我们在程序中利用列表存储了同一字段的多个值,然后进行了值绑定。最后执行execBatch()函数进行批处理。注意程序中利用QVariant(QVariant::String)来输入空值NULL,因为前面都是QString类型的,所以这里要使用QVariant::String 使格式一致化。

07. 事务操作

事务可以保证一个复杂的操作的原子性,就是对于一个数据库操作序列,这些操作要么全部做完,要么一条也不做,它是一个不可分割的工作单位。在Qt中,如果

底层的数据库引擎支持事务,那么QSqlDriver::hasFeature(QSqlDriver::Transactions)会返回true。可以使用QSqlDatabase::transaction()来启动一个事务,然后

编写一些希望在事务中执行的SQL语句,最后调用QSqlDatabase::commit()或者QSqlDatabase::rollback()。当使用事务时必须在创建查询以前就开始事务。

void MainWindow::on_pushButton_clicked()
{

    //启动事务
    QSqlDatabase::database().transaction();

    QSqlQuery query;

    query.prepare("insert into student values(?, ?)");
    QVariantList ints;
    ints << 10 << 11 << 12 << 13;
    query.addBindValue(ints);

    QVariantList names;
    names << "xiaoming" << "xiaogang" << "xiaohua" << QVariant(QVariant::String);
    query.addBindValue(names);

    if (!query.execBatch())
    {
        qDebug() << query.lastError().text();
    }



    //输出整张表
    query.exec("select * from student");
    while(query.next())
    {
        int id = query.value(0).toInt();
        QString name = query.value(1).toString();

        qDebug() << id << " " << name;
    }

    QSqlDatabase::database().commit();
}

08. 附录

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

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

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

昵称

取消
昵称表情代码图片

    暂无评论内容