QT数据库

八、数据库

  1. 准备工作

Qt本身并没有数据库功能,但是Qt支持调用其他主流的数据库产品。并且这些数据库产品指定了统一的Qt接口,实际上是一种数据库的中间件。

Qt支持以下数据库类型:

嵌入式常用的数据库式SQLite3,本体只有几兆大小,非常适合集成到嵌入式产品中,在Qt5版本及以上也集成了SQLite数据库,因此可以直接通过驱动名称连接SQLite。

数据库编程中需要用到以下几个相关类:

  • QSqlDatabase

数据库相关类,表示一个数据库连接。

  • QSqlQuery

数据库操作类,可以操作SQL语句

  • QSqlError

数据库错误信息类,用于收集数据库底层传递到Qt中的错误信息。

数据库相关类无法直接使用,需要在.pro项目配置文件中添加sql模块。

添加完成后要保存

  1. 连接数据库

主要通过QSqlDatabase类进行连接,相关函数实现:

// 获得一个数据库连接对象
// 参数位数据库类型,详见本章第一节表格(注意大小写)
// 返回值为连接对象
QSqlDatabase QSqlDatabase::​addDatabase(const QString & type)
[static]

// 设置数据库名称
// 参数因不同的数据类型表示不同的含义,对于SQLite,此函数表示数据文件名,此文件会在项目中构建目录中生成。
void QSqlDatabase::​setDatabaseName(const QString & name)

// 打开数据库连接
// 返回值为连接打开的结果,如果打开失败,可以通过lastError函数获得错误信息
bool QSqlDatabase::​open()

// 返回上一次的错误信息封装类
QSqlError QSqlDatabase::​lastError() const

// 从QSqlError对象中提取错误信息文本QString
QString QSqlError::​text() const

在构造函数中开启数据库连接,在析构函数中关闭数据连接。

// 返回数据库连接的打开状态
bool QSqlDatabase::​isOpen() const

// 关闭数据库连接
void QSqlDatabase::​close()

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    group = new QButtonGroup(this);
    group->addButton(ui->pushButtonInsert,1);
    group->addButton(ui->pushButtonDelete,2);
    group->addButton(ui->pushButtonUpdate,3);
    group->addButton(ui->pushButtonSelect,4);

    connect(group,SIGNAL(buttonClicked(int)),
            this,SLOT(btnsClickedSlot(int)));
    connectD2B();
}

Dialog::~Dialog()
{
    // 关闭数据库连接
    if(db.isOpen())
    {
        db.close();
    }

    delete ui;
}

// 连接数据库
void Dialog::connectD2B()
{
    // 获取数据库连接对象
    db = QSqlDatabase::addDatabase("QSQLITE");
    // 设置数据库名称
    db.setDatabaseName("book_manmgement.db");

    // 打开数据库连接
    bool ret = db.open();
    if(ret == true)
    {
        qDebug() << "打开成功" ;
    }
    else
    {
        // 数据库连接打开失败
        QSqlError errorInfo = db.lastError();
        QString text = errorInfo.text();
        QMessageBox::critical(this,"错误",text);
    }
}

void Dialog::btnsClickedSlot(int id)
{
    if(id == 1)
    {
        qDebug() << "增加" ;
    }
    else if(id == 2)
    {
        qDebug() << "删除" ;
    }
    else if(id == 3)
    {
        qDebug() << "修改" ;
    }
    else if(id == 4)
    {
        qDebug() << "查找" ;
    }
    else
    {

    }
}

3、创建表

建表语句:

CREATE TABLE book(id INTEGER PRIMARY KEY,name TEXT,price REAL,author TEXT);

CREATE TABLE book(
    id INTEGER PRIMARY KEY,
    name TEXT,
    price REAL,
    author TEXT
);

一个操作SQLite的可视化软件

下载链接:百度网盘 请输入提取码

提取码:hqyj 

// 执行sql语句
// 参数为执行的sql语句内容
// 返回值为执行的结果
bool QSqlQuery::​exec(const QString & query)

建表成功后,可以使用SQLiteSpy打开数据库文件查看表结构是否成功。

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    group = new QButtonGroup(this);
    group->addButton(ui->pushButtonInsert,1);
    group->addButton(ui->pushButtonDelete,2);
    group->addButton(ui->pushButtonUpdate,3);
    group->addButton(ui->pushButtonSelect,4);

    connect(group,SIGNAL(buttonClicked(int)),
            this,SLOT(btnsClickedSlot(int)));
    connectD2B();
}

Dialog::~Dialog()
{
    // 关闭数据库连接
    if(db.isOpen())
    {
        db.close();
    }

    delete ui;
}

// 连接数据库
void Dialog::connectD2B()
{
    // 获取数据库连接对象
    db = QSqlDatabase::addDatabase("QSQLITE");
    // 设置数据库名称
    db.setDatabaseName("book_manmgement.db");

    // 打开数据库连接
    bool ret = db.open();
    if(ret == true)
    {
        qDebug() << "打开成功" ;
        createTable();
    }
    else
    {
        // 数据库连接打开失败
        QSqlError errorInfo = db.lastError();
        QString text = errorInfo.text();
        QMessageBox::critical(this,"错误",text);
    }
}

// 创建表
void Dialog::createTable()
{
    QString sql = "CREATE TABLE book(id INTEGER PRIMARY KEY,name TEXT,price REAL,author TEXT)";

    sql = "CREATE TABLE book(\
        id INTEGER PRIMARY KEY,\
        name TEXT,\
        price REAL,\
        author TEXT\);";

    // 创建数据库操作类
    QSqlQuery sq;
    if(sq.exec(sql)) // 表创建成功
    {
        qDebug() << "建表成功";
    }
    else // 建表失败: 注意 建表成功或失败都很正常,如果要建的表已经存在,就会建表失败
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        qDebug() << "建表失败" << text;
    }
}

void Dialog::btnsClickedSlot(int id)
{
    if(id == 1)
    {
        qDebug() << "增加" ;
    }
    else if(id == 2)
    {
        qDebug() << "删除" ;
    }
    else if(id == 3)
    {
        qDebug() << "修改" ;
    }
    else if(id == 4)
    {
        qDebug() << "查找" ;
    }
    else
    {

    }
}

4、增删改

增删改操作都需要先录入用户输入,然后把用户如数的数据组装成SQL预取,最后执行。

组装SQL语句有两种方式:

  • 字符串拼接

这种方式虽然原理简单,但是容易拼接出错。且安全性低。

  • 预处理+占位符

推荐使用这种方式,这种方式需要先编写有占位符的预处理SQL语句,交给Qt,Qt内部就直到要执行的SQL语句格式,然后再进行参数与占位符的替换,最终执行。

占位符有两种风格:

  • Oracle风格

使用:字段的格式

UPDATE book SEname=:name,price=:price,author=:author WHERE id=:id;

  • ODBC风格

使用?的格式

-- 一个ODBC风格的预处理语句
INSERT INTO book VALUES(?,?,?,?);

// 预处理SQL语句,此时SQL语句并没有执行,只是送到Qt内部
// 参数为要预处理的SQL语句
// 返回值为预处理的结果
bool QSqlQuery::​prepare(const QString & query)

// 绑定ODBC风格的占位符参数,绑定时一定要注意参数的顺序
// 参数为要绑定的数据
void QSqlQuery::​addBindValue(const QVariant & val)

// 添加数据
void Dialog::insertData()
{
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名");
        return;
    }

    QString author = ui->lineEditAuthor->text();
    if(author == "")
    {
        QMessageBox::warning(this,"提示","请输入作者名");
        return;
    }

    int id = ui->spinBox->value();
    double price = ui->doubleSpinBox->value();

    // 预处理的SQL语句
    QString sql = "INSERT INTO book VALUES(?,?,?,?);";

    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);

    // 绑定参数
    sq.addBindValue(id);
    sq.addBindValue(name);
    sq.addBindValue(price);
    sq.addBindValue(author);

    // 执行绑定后的SQL语句
    if(sq.exec())
    {
       QMessageBox::information(this,"通知","数据插入成功");
    }
    else
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        QMessageBox::warning(this,"警告","数据插入失败");
    }
}

/绑定Oracle风格的占位符参数,绑定时可以乱序
// 参数1:占位符
/参数2:要绑定的数据
void QSqlQuery::​bindValue(const QString & placeholder, const QVariant & val)

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    group = new QButtonGroup(this);
    group->addButton(ui->pushButtonInsert,1);
    group->addButton(ui->pushButtonDelete,2);
    group->addButton(ui->pushButtonUpdate,3);
    group->addButton(ui->pushButtonSelect,4);

    connect(group,SIGNAL(buttonClicked(int)),
            this,SLOT(btnsClickedSlot(int)));
    connectD2B();
}

Dialog::~Dialog()
{
    // 关闭数据库连接
    if(db.isOpen())
    {
        db.close();
    }

    delete ui;
}

// 连接数据库
void Dialog::connectD2B()
{
    // 获取数据库连接对象
    db = QSqlDatabase::addDatabase("QSQLITE");
    // 设置数据库名称
    db.setDatabaseName("book_manmgement.db");

    // 打开数据库连接
    bool ret = db.open();
    if(ret == true)
    {
        qDebug() << "打开成功" ;
        createTable();
    }
    else
    {
        // 数据库连接打开失败
        QSqlError errorInfo = db.lastError();
        QString text = errorInfo.text();
        QMessageBox::critical(this,"错误",text);
    }
}

// 创建表
void Dialog::createTable()
{
    QString sql = "CREATE TABLE book(id INTEGER PRIMARY KEY,name TEXT,price REAL,author TEXT)";

    sql = "CREATE TABLE book(\
        id INTEGER PRIMARY KEY,\
        name TEXT,\
        price REAL,\
        author TEXT\);";

    // 创建数据库操作类
    QSqlQuery sq;
    if(sq.exec(sql)) // 表创建成功
    {
        qDebug() << "建表成功";
    }
    else // 建表失败: 注意 建表成功或失败都很正常,如果要建的表已经存在,就会建表失败
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        qDebug() << "建表失败" << text;
    }
}

// 添加数据
void Dialog::insertData()
{
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名");
        return;
    }

    QString author = ui->lineEditAuthor->text();
    if(author == "")
    {
        QMessageBox::warning(this,"提示","请输入作者名");
        return;
    }

    int id = ui->spinBox->value();
    double price = ui->doubleSpinBox->value();

    // 预处理的SQL语句
    QString sql = "INSERT INTO book VALUES(?,?,?,?);";

    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);

    // 绑定参数
    sq.addBindValue(id);
    sq.addBindValue(name);
    sq.addBindValue(price);
    sq.addBindValue(author);

    // 执行绑定后的SQL语句
    if(sq.exec())
    {
       QMessageBox::information(this,"通知","数据插入成功");
    }
    else
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        QMessageBox::warning(this,"警告","数据插入失败");
    }
}

// 删除按照id删除
void Dialog::deleteData()
{
    int id = ui->spinBox->value();
    // 查询表中id是否存在
    // TODO --

    // 预处理的SQL语句
    QString sql = "DELETE FROM book WHERE id=?";
    QSqlQuery sq;
    sq.prepare(sql); // 预处理

    // 绑定参数id
    sq.addBindValue(id);
    // 执行绑定后的sql语句
    if(sq.exec())
    {
        QMessageBox::information(this,"通知","数据删除成功");
    }
    else
    {
        // 获取错误信息封装类
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        QMessageBox::warning(this,"警告",text);
    }

}

// 更改数据
void Dialog::updateData()
{
    // 获取用户输入数据
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名");
        return;
    }
    QString author = ui->lineEditAuthor->text();
    if(author == "")
    {
        QMessageBox::warning(this,"提示","请输入作者名");
        return;
    }

    int id = ui->spinBox->value();
    double price = ui->doubleSpinBox->value();

    // 判断id是否再数据库中存在
    // TODO

    // 预处理语句(Oracle风格)
    QString sql = "UPDATE book SET name=:name,price=:price,author=:author WHERE id=:id";

    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);
    // 绑定参数
    sq.bindValue(":id",id);
    sq.bindValue(":price",price);
    sq.bindValue(":author",author);
    sq.bindValue(":name",name);

    // 执行绑定后的数据
    if(sq.exec())
    {
        qDebug() << "更新成功" ;
        QMessageBox::information(this,"提示","数据更改成功");
    }
    else
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        QMessageBox::warning(this,"警告",text);
    }
}

void Dialog::btnsClickedSlot(int id)
{
    if(id == 1)
    {
        qDebug() << "增加" ;
        insertData();
    }
    else if(id == 2)
    {
        qDebug() << "删除" ;
        deleteData();
    }
    else if(id == 3)
    {
        qDebug() << "修改" ;
        updateData();
    }
    else if(id == 4)
    {
        qDebug() << "查找" ;
    }
    else
    {

    }
}

5、查询

5.1 全查

 相关函数

// 判断查询结果有无数据,如果有则移动游标并取出,没有返回false
bool QSqlQuery::​next()

// 按照字段序号取出对应的值,序号从0开始
// 返回值为QVariant类型,可以根据需要直接转换为所需数据类型
QVariant QSqlQuery::​value(int index) const

// 按照字段名称取出对应的值
/返回值为QVariant类型,可以根据需要直接转换为所需数据类型 
QVariant QSqlQuery::​value(const QString & name) const

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    group = new QButtonGroup(this);
    group->addButton(ui->pushButtonInsert,1);
    group->addButton(ui->pushButtonDelete,2);
    group->addButton(ui->pushButtonUpdate,3);
    group->addButton(ui->pushButtonSelect,4);

    connect(group,SIGNAL(buttonClicked(int)),
            this,SLOT(btnsClickedSlot(int)));
    connectD2B();
}

Dialog::~Dialog()
{
    // 关闭数据库连接
    if(db.isOpen())
    {
        db.close();
    }

    delete ui;
}

// 连接数据库
void Dialog::connectD2B()
{
    // 获取数据库连接对象
    db = QSqlDatabase::addDatabase("QSQLITE");
    // 设置数据库名称
    db.setDatabaseName("book_manmgement.db");

    // 打开数据库连接
    bool ret = db.open();
    if(ret == true)
    {
        qDebug() << "打开成功" ;
        createTable();
    }
    else
    {
        // 数据库连接打开失败
        QSqlError errorInfo = db.lastError();
        QString text = errorInfo.text();
        QMessageBox::critical(this,"错误",text);
    }
}

// 创建表
void Dialog::createTable()
{
    QString sql = "CREATE TABLE book(id INTEGER PRIMARY KEY,name TEXT,price REAL,author TEXT)";

    sql = "CREATE TABLE book(\
        id INTEGER PRIMARY KEY,\
        name TEXT,\
        price REAL,\
        author TEXT\);";

    // 创建数据库操作类
    QSqlQuery sq;
    if(sq.exec(sql)) // 表创建成功
    {
        qDebug() << "建表成功";
    }
    else // 建表失败: 注意 建表成功或失败都很正常,如果要建的表已经存在,就会建表失败
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        qDebug() << "建表失败" << text;
    }
}

// 添加数据
void Dialog::insertData()
{
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名");
        return;
    }

    QString author = ui->lineEditAuthor->text();
    if(author == "")
    {
        QMessageBox::warning(this,"提示","请输入作者名");
        return;
    }

    int id = ui->spinBox->value();
    double price = ui->doubleSpinBox->value();

    // 预处理的SQL语句
    QString sql = "INSERT INTO book VALUES(?,?,?,?);";

    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);

    // 绑定参数
    sq.addBindValue(id);
    sq.addBindValue(name);
    sq.addBindValue(price);
    sq.addBindValue(author);

    // 执行绑定后的SQL语句
    if(sq.exec())
    {
       QMessageBox::information(this,"通知","数据插入成功");
    }
    else
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        QMessageBox::warning(this,"警告","数据插入失败");
    }
}

// 删除按照id删除
void Dialog::deleteData()
{
    int id = ui->spinBox->value();
    // 查询表中id是否存在
    if(!isDataExists(id))
    {
        QMessageBox::warning(this,"提示","没有找到要修改的数据");
        return;
    }

    // 预处理的SQL语句
    QString sql = "DELETE FROM book WHERE id=?";
    QSqlQuery sq;
    sq.prepare(sql); // 预处理

    // 绑定参数id
    sq.addBindValue(id);
    // 执行绑定后的sql语句
    if(sq.exec())
    {
        QMessageBox::information(this,"通知","数据删除成功");
    }
    else
    {
        // 获取错误信息封装类
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        QMessageBox::warning(this,"警告",text);
    }

}

// 更改数据
void Dialog::updateData()
{
    // 获取用户输入数据
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名");
        return;
    }
    QString author = ui->lineEditAuthor->text();
    if(author == "")
    {
        QMessageBox::warning(this,"提示","请输入作者名");
        return;
    }

    int id = ui->spinBox->value();
    double price = ui->doubleSpinBox->value();

    // 判断id是否再数据库中存在
    if(!isDataExists(id))
    {
        QMessageBox::warning(this,"提示","没有找到要修改的数据");
        return;
    }

    // 预处理语句(Oracle风格)
    QString sql = "UPDATE book SET name=:name,price=:price,author=:author WHERE id=:id";

    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);
    // 绑定参数
    sq.bindValue(":id",id);
    sq.bindValue(":price",price);
    sq.bindValue(":author",author);
    sq.bindValue(":name",name);

    // 执行绑定后的数据
    if(sq.exec())
    {
        qDebug() << "更新成功" ;
        QMessageBox::information(this,"提示","数据更改成功");
    }
    else
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        QMessageBox::warning(this,"警告",text);
    }
}

// 查找全部数据
void Dialog::selectAll()
{
   ui->textBrowser->clear();
   QString sql = "SELECT * FROM book";
   QSqlQuery sq;
   if(sq.exec(sql))
   {
       while(sq.next()) // 循环取出
       {
           // 取出一条记录中的每个字段值
           QString id = sq.value(0).toString();
           QString name = sq.value(1).toString();
           QString price = sq.value("price").toString();
           QString author = sq.value("author").toString();

           // 显示
           QString text = id.append("-")+name.append("-")+price.append("-")+author;
           ui->textBrowser->append(text);
       }
   }
}

// 判断数据是否存在,采用字符串拼接
bool Dialog::isDataExists(int id)
{
    QString idText = QString::number(5.2id);
    QString sql = "SELECT * FROM book WHERE id=";
    sql.append(idText); // 拼接只为证明可行,但不建议
    QSqlQuery sq;
    if(sq.exec(sql))
    {
        return sq.next();
    }
    else
    {
        return false;
    }
}

void Dialog::btnsClickedSlot(int id)
{
    if(id == 1)
    {
        qDebug() << "增加" ;
        insertData();
    }
    else if(id == 2)
    {
        qDebug() << "删除" ;
        deleteData();
    }
    else if(id == 3)
    {
        qDebug() << "修改" ;
        updateData();
    }
    else if(id == 4)
    {
        qDebug() << "查找" ;
        selectAll();
    }
    else
    {

    }
}

5.2 模糊查询

可以使用LIKE关键字配合两个通配符实现模糊查询。

  • %

任意多个(0,1........n)个字符

  • _

任意一个字符

【例子】查询‘春’字辈人员信息

SELECT * FROM book WHERE name LIKE "_春%"

【例子】查询姓名中包含”春“的人员信息

SELECT * FROM book WHERE name LIKE "%春%"

// 模糊查询,按照书名进行查询
void Dialog::selectLike()
{
    // 获取用户输入信息
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名");
        return;
    }

    // 预处理SQL
    QString sql = "SELECT * FROM book WHERE name LIKE ?";
    QSqlQuery sq;

    // 预处理
    sq.prepare(sql);
    sq.addBindValue(name.prepend("%").append("%")); // 通配符
    if(sq.exec())
    {
        // 是否查到状态
        bool reState = true;
        // 清空上次显示
        ui->textBrowser->clear();
        while(sq.next())
        {
            QString id = sq.value(0).toString();
            QString name = sq.value(1).toString();
            QString price = sq.value(2).toString();
            QString author = sq.value(3).toString();

            // 显示
            QString text = id.append("-")+name.append("-")+price.append("-")+author;
            ui->textBrowser->append(text);
            reState = false;
        }
        if(reState)
        {
            QMessageBox::information(this,"提示","没有找到相关数据");
        }
    }
    else
    {
        QString text = sq.lastError().text();
        text.prepend("查询失败:");
        QMessageBox::critical(this,"错误",text);
    }
}

5.1 全查

 相关函数

// 判断查询结果有无数据,如果有则移动游标并取出,没有返回false
bool QSqlQuery::next()

// 按照字段序号取出对应的值,序号从0开始
// 返回值为QVariant类型,可以根据需要直接转换为所需数据类型
QVariant QSqlQuery::value(int index) const

// 按照字段名称取出对应的值
// 返回值为QVariant类型,可以根据需要直接转换为所需数据类型 
QVariant QSqlQuery::value(const QString & name) const

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    group = new QButtonGroup(this);
    group->addButton(ui->pushButtonInsert,1);
    group->addButton(ui->pushButtonDelete,2);
    group->addButton(ui->pushButtonUpdate,3);
    group->addButton(ui->pushButtonSelect,4);

    connect(group,SIGNAL(buttonClicked(int)),
            this,SLOT(btnsClickedSlot(int)));
    connectD2B();
}

Dialog::~Dialog()
{
    // 关闭数据库连接
    if(db.isOpen())
    {
        db.close();
    }

    delete ui;
}

// 连接数据库
void Dialog::connectD2B()
{
    // 获取数据库连接对象
    db = QSqlDatabase::addDatabase("QSQLITE");
    // 设置数据库名称
    db.setDatabaseName("book_manmgement.db");

    // 打开数据库连接
    bool ret = db.open();
    if(ret == true)
    {
        qDebug() << "打开成功" ;
        createTable();
    }
    else
    {
        // 数据库连接打开失败
        QSqlError errorInfo = db.lastError();
        QString text = errorInfo.text();
        QMessageBox::critical(this,"错误",text);
    }
}

// 创建表
void Dialog::createTable()
{
    QString sql = "CREATE TABLE book(id INTEGER PRIMARY KEY,name TEXT,price REAL,author TEXT)";

    sql = "CREATE TABLE book(\
        id INTEGER PRIMARY KEY,\
        name TEXT,\
        price REAL,\
        author TEXT\);";

    // 创建数据库操作类
    QSqlQuery sq;
    if(sq.exec(sql)) // 表创建成功
    {
        qDebug() << "建表成功";
    }
    else // 建表失败: 注意 建表成功或失败都很正常,如果要建的表已经存在,就会建表失败
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        qDebug() << "建表失败" << text;
    }
}

// 添加数据
void Dialog::insertData()
{
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名");
        return;
    }

    QString author = ui->lineEditAuthor->text();
    if(author == "")
    {
        QMessageBox::warning(this,"提示","请输入作者名");
        return;
    }

    int id = ui->spinBox->value();
    double price = ui->doubleSpinBox->value();

    // 预处理的SQL语句
    QString sql = "INSERT INTO book VALUES(?,?,?,?);";

    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);

    // 绑定参数
    sq.addBindValue(id);
    sq.addBindValue(name);
    sq.addBindValue(price);
    sq.addBindValue(author);

    // 执行绑定后的SQL语句
    if(sq.exec())
    {
       QMessageBox::information(this,"通知","数据插入成功");
    }
    else
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        QMessageBox::warning(this,"警告","数据插入失败");
    }
}

// 删除按照id删除
void Dialog::deleteData()
{
    int id = ui->spinBox->value();
    // 查询表中id是否存在
    if(!isDataExists(id))
    {
        QMessageBox::warning(this,"提示","没有找到要修改的数据");
        return;
    }

    // 预处理的SQL语句
    QString sql = "DELETE FROM book WHERE id=?";
    QSqlQuery sq;
    sq.prepare(sql); // 预处理

    // 绑定参数id
    sq.addBindValue(id);
    // 执行绑定后的sql语句
    if(sq.exec())
    {
        QMessageBox::information(this,"通知","数据删除成功");
    }
    else
    {
        // 获取错误信息封装类
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        QMessageBox::warning(this,"警告",text);
    }

}

// 更改数据
void Dialog::updateData()
{
    // 获取用户输入数据
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名");
        return;
    }
    QString author = ui->lineEditAuthor->text();
    if(author == "")
    {
        QMessageBox::warning(this,"提示","请输入作者名");
        return;
    }

    int id = ui->spinBox->value();
    double price = ui->doubleSpinBox->value();

    // 判断id是否再数据库中存在
    if(!isDataExists(id))
    {
        QMessageBox::warning(this,"提示","没有找到要修改的数据");
        return;
    }

    // 预处理语句(Oracle风格)
    QString sql = "UPDATE book SET name=:name,price=:price,author=:author WHERE id=:id";

    // 预处理
    QSqlQuery sq;
    sq.prepare(sql);
    // 绑定参数
    sq.bindValue(":id",id);
    sq.bindValue(":price",price);
    sq.bindValue(":author",author);
    sq.bindValue(":name",name);

    // 执行绑定后的数据
    if(sq.exec())
    {
        qDebug() << "更新成功" ;
        QMessageBox::information(this,"提示","数据更改成功");
    }
    else
    {
        QSqlError errInfo = sq.lastError();
        QString text = errInfo.text();
        QMessageBox::warning(this,"警告",text);
    }
}

// 查找全部数据
void Dialog::selectAll()
{
   ui->textBrowser->clear();
   QString sql = "SELECT * FROM book";
   QSqlQuery sq;
   if(sq.exec(sql))
   {
       while(sq.next()) // 循环取出
       {
           // 取出一条记录中的每个字段值
           QString id = sq.value(0).toString();
           QString name = sq.value(1).toString();
           QString price = sq.value("price").toString();
           QString author = sq.value("author").toString();

           // 显示
           QString text = id.append("-")+name.append("-")+price.append("-")+author;
           ui->textBrowser->append(text);
       }
   }
}

// 判断数据是否存在,采用字符串拼接
bool Dialog::isDataExists(int id)
{
    QString idText = QString::number(5.2id);
    QString sql = "SELECT * FROM book WHERE id=";
    sql.append(idText); // 拼接只为证明可行,但不建议
    QSqlQuery sq;
    if(sq.exec(sql))
    {
        return sq.next();
    }
    else
    {
        return false;
    }
}

void Dialog::btnsClickedSlot(int id)
{
    if(id == 1)
    {
        qDebug() << "增加" ;
        insertData();
    }
    else if(id == 2)
    {
        qDebug() << "删除" ;
        deleteData();
    }
    else if(id == 3)
    {
        qDebug() << "修改" ;
        updateData();
    }
    else if(id == 4)
    {
        qDebug() << "查找" ;
        selectAll();
    }
    else
    {

    }
}

5.2 模糊查询

可以使用LIKE关键字配合两个通配符实现模糊查询。

  • %

任意多个(0,1........n)个字符

  • _

任意一个字符

【例子】查询‘春’字辈人员信息

SELECT * FROM book WHERE name LIKE "_春%"

【例子】查询姓名中包含”春“的人员信息

SELECT * FROM book WHERE name LIKE "%春%"

// 模糊查询,按照书名进行查询
void Dialog::selectLike()
{
    // 获取用户输入信息
    QString name = ui->lineEdit->text();
    if(name == "")
    {
        QMessageBox::warning(this,"提示","请输入书名");
        return;
    }

    // 预处理SQL
    QString sql = "SELECT * FROM book WHERE name LIKE ?";
    QSqlQuery sq;

    // 预处理
    sq.prepare(sql);
    sq.addBindValue(name.prepend("%").append("%")); // 通配符
    if(sq.exec())
    {
        // 是否查到状态
        bool reState = true;
        // 清空上次显示
        ui->textBrowser->clear();
        while(sq.next())
        {
            QString id = sq.value(0).toString();
            QString name = sq.value(1).toString();
            QString price = sq.value(2).toString();
            QString author = sq.value(3).toString();

            // 显示
            QString text = id.append("-")+name.append("-")+price.append("-")+author;
            ui->textBrowser->append(text);
            reState = false;
        }
        if(reState)
        {
            QMessageBox::information(this,"提示","没有找到相关数据");
        }
    }
    else
    {
        QString text = sq.lastError().text();
        text.prepend("查询失败:");
        QMessageBox::critical(this,"错误",text);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/410689.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux进程 ----- 信号处理

前言 从信号产生到信号保存&#xff0c;中间经历了很多&#xff0c;当操作系统准备对信号进行处理时&#xff0c;还需要判断时机是否 “合适”&#xff0c;在绝大多数情况下&#xff0c;只有在 “合适” 的时机才能处理信号&#xff0c;即调用信号的执行动作。 一、信号的处理…

什么是代码签名证书中的“硬证书”?

代码签名证书是用于验证和签名软件程序的一种数字证书。使用代码签名证书&#xff0c;可以保护代码完整性、防止非法篡改&#xff0c;标识软件发行商的身份并确保软件来源可信。按不同验证级别&#xff0c;代码签名证书分为扩展验证型EV代码签名证书、企业验证型OV代码签名证书…

babylonjs入门模

基于babylonjs封装的一些功能和插件 &#xff0c;希望有更多的小伙伴一起玩babylonjs&#xff1b; 欢迎加群&#xff1a;464146715 官方文档 中文文档 最小模版 ​ 代码如下&#xff1a; 在react中使用 import React, { FC, useCallback, useEffect, useRef, useState } f…

LINE封号全面解析:原因、判断方法与申诉渠道

在LINE中被封锁有两个方面&#xff1a;一是你被好友屏蔽&#xff0c;另一是遭到平台官方的封锁。通常用户会用“停权”来代表LINE的官方封锁&#xff0c;在实际操作上&#xff0c;所谓的停权并不意味着你的账户完全无法使用&#xff0c;只是没办法与好友发送消息&#xff0c;更…

聊一聊EGO-Planner膨胀系数的大小对无人机避障飞行的影响

EGO-Planner简介 EGO-Planner作为业界知名的无人机轨迹规划算法&#xff0c;其优势在于能够在复杂环境中快速规划出安全、平滑且动态可行的飞行轨迹。在这个算法中&#xff0c;膨胀系数发挥着关键作用。它通过扩大障碍物的感知范围&#xff0c;提供额外的安全边距&#xff0c;…

如何使用Lychee+cpolar搭建本地私人图床并实现远程访问存储图片

文章目录 1.前言2. Lychee网站搭建2.1. Lychee下载和安装2.2 Lychee网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 图床作为图片集中存放的服务网站&#xff0c;可以看做是云存储的一部分&#xff0c;既可…

c++ Qt 网络连接

1、基础概念 1.1 TCP/UDP TCP 是一种面向连接的传输层协议&#xff0c;它能提供高可靠性通信(即数据无误、数据无丢失、 数据无失序、数据无重复到达的通信) 适用情况&#xff1a; 1.SN/QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议 2、适合于对传输质量要求较…

网站开发--详解Servlet

&#x1f495;"Echo"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;网站开发–详解Servlet 一.基本介绍 tomcat是Java中开发服务器的重要的一个工具,任何开发的服务器都要部署在tomcat之上,可以说tomcat是所有服务器的底座,为了更好的操作http,to…

python 进程笔记一 (概念+示例代码)

1. 进程的概念 进程是资源分配的最小单位&#xff0c;也是线程的容器&#xff0c;线程&#xff08;python 线程 &#xff08;概念示例代码&#xff09;&#xff09;是CPU调度的基本单位&#xff0c;一个进程包括多个线程。 程序&#xff1a;例如xxx.py是一个程序 进程&#xf…

C++初阶 | [八] (下) vector 模拟实现

摘要&#xff1a;vector 模拟实现讲解&#xff08;附代码示例&#xff09;&#xff0c;隐藏的浅拷贝&#xff0c;迭代器失效 在进行 vector 的模拟实现之前&#xff0c;我们先粗略浏览一下 stl_vector.h 文件中的源码来确定模拟实现的大体框架。 这里提供一些粗略浏览源码的技巧…

如何使用GAP-Burp-Extension扫描潜在的参数和节点

关于GAP-Burp-Extension GAP-Burp-Extension是一款功能强大的Burp扩展&#xff0c;该工具在getAllParams扩展的基础上进行了升级&#xff0c;该工具不仅可以帮助广大研究人员在安全审计过程中扫描潜在的参数&#xff0c;而且还可以搜索潜在的链接并使用这些参数进行测试&#…

HarmonyOS—代码Code Linter检查

Code Linter代码检查 Code-Linter针对ArkTS/TS代码进行最佳实践、编程规范方面的检查&#xff0c;目前还会检查ArkTS语法规则。开发者可根据扫描结果中告警提示手工修复代码缺陷&#xff0c;或者执行一键式自动修复&#xff0c;在代码开发阶段&#xff0c;确保代码质量。 检查…

Linux之项目部署与发布

目录 一、Nginx配置安装&#xff08;自启动&#xff09; 1.一键安装4个依赖 2. 下载并解压安装包 3. 安装Nginx 4. 启动 nginx 服务 5. 对外开放端口 6. 配置开机自启动 7.修改/etc/rc.d/rc.local的权限 二、后端部署tomcat负载均衡 1. 准备2个tomcat 2. 修改端口 3…

【Vue3】学习watch监视:深入了解Vue3响应式系统的核心功能(上)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

基于Java的艺培管理解决方案

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

抖音小程序获取手机号

1、* 手机号获取和登录需要分开 &#xff08;规定&#xff09; 2、 抖音小程序首先得先通过试运营 没有通过试运营的 会提示没有权限 getPhoneNumber:fail auth deny 3、上代码 <button class"phone toutiaoSq" v-if"!userInfo.phone && isLogin&…

[AutoSar]BSW_Com03 DBC详解 (一)

目录 关键词平台说明一、DBC 定义1.1 相关工具 二、主要组成部分介绍2.1 Networks2.2 ECUs2.3 Network nodes2.4 messages2.5 signal2.6 Value Tables 三、主要组成部分关系图 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &am…

本地项目如何上传到gitee

文章目录 一、在gitee上新建远程仓库二、初始化本地仓库三、执行git命令上传代码 一、在gitee上新建远程仓库 仓库名称必填&#xff0c;路径自动跟仓库名称保持一致 解释说明&#xff1a; 仓库名称&#xff1a;必填&#xff0c;每个仓库都需要有一个名称&#xff0c;同一个码…

tkinterFrame框架+标签框架LabelFrame+Toplevel窗口的使用

1.在tkinter中&#xff0c;Frame是一个容器小部件用于组织和管理其他小部件。它可以作为一个独立的可见区域&#xff0c;也可以作为其他小部件的父容器。 import tkinter as tk import tkinter.ttk as ttk import tkinter.messagebox as mbm tk.Tk() m.title("tkinter L…

Vue事件处理之v-on

1. 使用及定义 定义方法 function 方法名称(接受的event或是什么都不写) {//不管方法后括号内写与不写event,都可以接受到方法内表达式 }//定义一个接受参数的方法,此时也会在传入event function 方法名称(传入参数) {//可接受传入参数与event方法内表达式 } //定义一个接受参…
最新文章