Qt--database--addition, deletion, modification and query operations

1. Introduction to Qt database

Qt is only used as a medium to operate the database, and it does not have the function of the database itself. Therefore, in addition to Qt, the corresponding database software needs to be installed in the computer. However, because the SQLite database is relatively light, Qt integrates the SQLite database. This database is an embedded The most commonly used database in .

Actually Qt supports the following types of database products:

To use a database in a Qt project, the sql module must be added to the .pro project configuration file.

2. Connection and shutdown

The main classes used are the database connection class QSqlDatabase and the database error message class QSqlError, and the functions involved are:

// 获得一个基于SQLite的数据库连接对象
QSqlDatabase QSqlDatabase::addDatabase("QSQLITE") [static]// 设置SQLite数据库文件的名称(不同的数据库此函数表示不同的功能)
// 在运行之后,此文件会在构建目录中生成
void QSqlDatabase::setDatabaseName(const QString & name)// 打开数据库连接
// 返回值是打开的结果,如果打开失败,可以通过lastError()函数获得错误信息
bool QSqlDatabase::open()// 获得上一次数据库的错误信息
QSqlError QSqlDatabase::lastError() const
// 可以通过下面的函数把错误信息转换为字符串(实际上这些信息来自于底层数据库)
QString QSqlError::text() const// 判断连接是否打开
bool QSqlDatabase::isOpen() const// 关闭连接
void QSqlDatabase::close()

After the connection is successful, the database file will be generated.

3. Create table

QSqlQuery is mainly used to execute SQL statements, and the related functions are as follows.

// 执行SQL语句
// 参数是要执行的SQL语句
// 返回值是语句本身执行的结果,并不是数据操作的结果
bool QSqlQuery::exec(const QString & query)
// 用法与之前的同名函数完全相同
QSqlError QSqlQuery::lastError() constRefer to the table creation statement:

 

CREATE TABLE customer(id INTEGER PRIMARY KEY,name TEXT,money REAL,rate REAL);

After the table is built successfully, you can directly go to the build directory and use the SQLiteSpy tool to open the .db file to verify whether the table is built successfully.

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include<QtWidgets>
#include<QDebug>
#include<QButtonGroup>
#include<QSqlDatabase>
#include<QSqlError>
#include<QSqlQuery>
namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;
    QButtonGroup *group;
    QSqlDatabase db;//数据库连接对象
    void connect2Db();//连接到数据库
    void createTable();//建表

private slots:
    void btnsClickedSlot(int);

};

#endif // DIALOG_H

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)));
    connect2Db();
}
void Dialog::btnsClickedSlot(int id)
{
    if(id==1)
    {
      
    }else if(id==2)
    {

    }else if(id==3)
    {

    }else if(id==4)
    {

    }
}

Dialog::~Dialog()//析构函数销毁创建的对象
{
    //如果数据库连接打开了,则关闭
    if(db.isOpen())
      db.close();
    delete ui;
}

void Dialog::connect2Db()
{
    //获得一个基于SQLite的数据库连接对象
    db=QSqlDatabase::addDatabase("QSQLITE");
    //设置数据库文件的名称
    db.setDatabaseName("bank_manage.db");
    //打开连接
    if(db.open())
    {
        qDebug()<<"连接打开成功!";
        createTable();
    }else
    {
        //拿到错误信息
        QString text=db.lastError().text();
        //展示错误信息
        QMessageBox::critical(this,"错误",text);
    }
}

void Dialog::createTable()
{
    QString sql="CREATE TABLE customer(id INTERGER PERIMARY KEY,name TEXT,money REAL,rate REAL)";
    //数据库操作类
    QSqlQuery sq;
    if(sq.exec(sql))
    {
        qDebug()<<"建表成功!";
    }else
    {
        qDebug()<<sq.lastError().text();//上一次操作的错误信息
    }
}

dialog.ui

4. Additions, deletions and modifications

The operation methods of adding, deleting, and modifying are similar. It is necessary to pay attention not to use splicing to create SQL statements with parameters. The reasons are as follows:

  • Stitching is complicated and error-prone
  • Security issues that are prone to SQL injection

Qt uses placeholder replacement to "splicing" SQL statements. There are two ways of placeholder replacement:

  • ODBC style (?)
  • Oracle style colon-name 
// 预处理带有占位符的SQL语句
// 参数为预处理的SQL语句
// 返回值是预处理的结果
bool QSqlQuery::prepare(const QString & query)// 添加绑定数据
// 参数为要绑定的数据,各种类型直接传递即可,传递的顺序要按照?的顺序
void QSqlQuery::addBindValue(const QVariant & val)// 执行预处理的SQL语句
// 语句本身是否成功执行
bool QSqlQuery::exec()

1. Add data

dialog.h

private:
    Ui::Dialog *ui;
    QButtonGroup *group;
    QSqlDatabase db;//数据库连接对象
    void connect2Db();//连接到数据库
    void createTable();//建表
    void insertData();//增加

dialog.cpp


void Dialog::btnsClickedSlot(int id)
{
    if(id==1)
    {
       insertData();//添加数据
    }else if(id==2)
    {

    }else if(id==3)
    {

    }else if(id==4)
    {

    }
}
void Dialog::insertData()
{
    //如果姓名为空,引导用户输入
    QString name=ui->lineEdit->text();
    if(name=="")
    {
        QMessageBox::warning(this,"提示","请输入姓名:");
        return;
    }
    int id=ui->spinBoxId->value();
    double money=ui->doubleSpinBox->value();
    double rate=ui->doubleSpinBoxLv->value();
    //操作类对象
    QSqlQuery sq;
    //预处理的SQL语句
    QString sql="INSERT INTO customer VALUES(?,?,?,?)";
    //预处理
    sq.prepare(sql);
    //绑定数据 按照顺序添加数据
    sq.addBindValue(id);
    sq.addBindValue(name);
    sq.addBindValue(money);
    sq.addBindValue(rate);
    //执行sql语句(执行的是内部预处理的语句)
    if(sq.exec())
    {
        QMessageBox::information(this,"通知","成功插入一条数据!");
    }else
    {
        QString text=sq.lastError().text();
        QMessageBox::warning(this,"提示",text);
    }

}

 

 2. Delete data

dialog.h

private:
    Ui::Dialog *ui;
    QButtonGroup *group;
    QSqlDatabase db;//数据库连接对象
    void connect2Db();//连接到数据库
    void createTable();//建表
    void insertData();//增加
    void deleteData();//删除

dialog.cpp


void Dialog::btnsClickedSlot(int id)
{
    if(id==1)
    {
       insertData();
    }else if(id==2)
    {
       deleteData();
    }else if(id==3)
    {
       
    }else if(id==4)
    {

    }
}
void Dialog::deleteData()
{
    int id=ui->spinBoxId->value();
    //判断表中数据是否存在

    //预处理的SQL语句
    QString sql="DELETE FROM customer WHERE id=?";
    QSqlQuery sq;
    sq.prepare(sql);
    sq.addBindValue(ui->spinBoxId->value());
    //执行sql语句(执行的是内部预处理的语句)
    if(sq.exec())
    {
        QMessageBox::information(this,"通知","成功删除一条数据!");
    }else
    {
        QString text=sq.lastError().text();
        QMessageBox::warning(this,"提示",text);
    }
}

 

3. Modify data

dialog.h

private:
    Ui::Dialog *ui;
    QButtonGroup *group;
    QSqlDatabase db;//数据库连接对象
    void connect2Db();//连接到数据库
    void createTable();//建表
    void insertData();//增加
    void deleteData();//删除
    void updateData();//修改

dialog.cpp


void Dialog::btnsClickedSlot(int id)
{
    if(id==1)
    {
       insertData();
    }else if(id==2)
    {
       deleteData();
    }else if(id==3)
    {
       updateData();
    }else if(id==4)
    {

    }
}

void Dialog::updateData()
{
    //如果姓名为空,引导用户输入
    QString name=ui->lineEdit->text();
    if(name=="")
    {
        QMessageBox::warning(this,"提示","请输入姓名:");
        return;
    }
    int id=ui->spinBoxId->value();
    //判断更新数据是否存在

    double money=ui->doubleSpinBox->value();
    double rate=ui->doubleSpinBoxLv->value();

    //操作类对象
    QSqlQuery sq;
    //预处理的SQL语句
    QString sql="UPDATE customer SET name=?,money=?,rate=? WHERE id=?";
    //预处理
    sq.prepare(sql);
    //绑定
    sq.addBindValue(name);
    sq.addBindValue(money);
    sq.addBindValue(rate);
    sq.addBindValue(id);
    //执行
    if(sq.exec())
    {
        QMessageBox::information(this,"通知","成功修改一条数据!");
    }else
    {
        QString text=sq.lastError().text();
        QMessageBox::warning(this,"提示",text);
    }
}

5. Query

Queries work similarly to iterator pointers, and the related functions are as follows.

// 取出结果中的下一个记录,如果没有下一个记录则返回false
bool QSqlQuery::next()// 按照列序号取出对应的列数据
// 参数是列序号,从0开始
// 返回值是取出的数据,支持各种常见类型的转换
QVariant QSqlQuery::value(int index) const// 按照列名取出对应的列数据
// 参数是列名
// 返回值是取出的数据,支持各种常见类型的转换
QVariant QSqlQuery::value(const QString & name) const

dialog.h

private:
    Ui::Dialog *ui;
    QButtonGroup *group;
    QSqlDatabase db;//数据库连接对象
    void connect2Db();//连接到数据库
    void createTable();//建表
    void insertData();//增加
    void deleteData();//删除
    void updateData();//修改
    void selectAll();//查询所有

dialog.cpp


void Dialog::btnsClickedSlot(int id)
{
    if(id==1)
    {
       insertData();
    }else if(id==2)
    {
       deleteData();
    }else if(id==3)
    {
       updateData();
    }else if(id==4)
    {
       selectAll();
    }
}


void Dialog::selectAll()
{
    QString sql="SELECT * FROM customer";
    QSqlQuery sq;
    if(sq.exec(sql))
    {
        //清空上次显示结果
        ui->textBrowser->clear();
        while(sq.next())
        {
            //取出每列数据
            //方式一:按照序号(0,1,2,3...)取出
            QString id=sq.value(0).toString();
            //方式二:按照列名取出
            QString name=sq.value("name").toString();
            QString money=sq.value("money").toString();
            QString rate=sq.value("rate").toString();
            QString text;
            text=text+id.append("-")+name.append("-")+money.append("-")+rate;
            //展示数据
            ui->textBrowser->append(text);
        }
    }else
    {
        QString text=sq.lastError().text();
        QMessageBox::warning(this,"提示",text);
    }
}

 Determine whether the data exists

dialog.h

private:
    Ui::Dialog *ui;
    QButtonGroup *group;
    QSqlDatabase db;//数据库连接对象
    void connect2Db();//连接到数据库
    void createTable();//建表
    void insertData();//增加
    void deleteData();//删除
    void updateData();//修改
    void selectAll();//查询所有
    bool isDataExists(int);//判断某个id的数据是否存在

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)));
    connect2Db();
}
void Dialog::btnsClickedSlot(int id)
{
    if(id==1)
    {
       insertData();
    }else if(id==2)
    {
       deleteData();
    }else if(id==3)
    {
       updateData();
    }else if(id==4)
    {
       selectAll();
    }
}

Dialog::~Dialog()//析构函数销毁创建的对象
{
    //如果数据库连接打开了,则关闭
    if(db.isOpen())
      db.close();
    delete ui;
}

void Dialog::connect2Db()
{
    //获得一个基于SQLite的数据库连接对象
    db=QSqlDatabase::addDatabase("QSQLITE");
    //设置数据库文件的名称
    db.setDatabaseName("bank_manage.db");
    //打开连接
    if(db.open())
    {
        qDebug()<<"连接打开成功!";
        createTable();
    }else
    {
        //拿到错误信息
        QString text=db.lastError().text();
        //展示错误信息
        QMessageBox::critical(this,"错误",text);
    }
}

void Dialog::createTable()
{
    QString sql="CREATE TABLE customer(id INTERGER PERIMARY KEY,name TEXT,money REAL,rate REAL)";
    //数据库操作类
    QSqlQuery sq;
    if(sq.exec(sql))
    {
        qDebug()<<"建表成功!";
    }else
    {
        qDebug()<<sq.lastError().text();//上一次操作的错误信息
    }
}

void Dialog::insertData()
{
    //如果姓名为空,引导用户输入
    QString name=ui->lineEdit->text();
    if(name=="")
    {
        QMessageBox::warning(this,"提示","请输入姓名:");
        return;
    }
    int id=ui->spinBoxId->value();
    double money=ui->doubleSpinBox->value();
    double rate=ui->doubleSpinBoxLv->value();
    //操作类对象
    QSqlQuery sq;
    //预处理的SQL语句
    QString sql="INSERT INTO customer VALUES(?,?,?,?)";
    //预处理
    sq.prepare(sql);
    //绑定数据 按照顺序添加数据
    sq.addBindValue(id);
    sq.addBindValue(name);
    sq.addBindValue(money);
    sq.addBindValue(rate);
    //执行sql语句(执行的是内部预处理的语句)
    if(sq.exec())
    {
        QMessageBox::information(this,"通知","成功插入一条数据!");
    }else
    {
        QString text=sq.lastError().text();
        QMessageBox::warning(this,"提示",text);
    }

}

void Dialog::deleteData()
{
    int id=ui->spinBoxId->value();
    //判断表中数据是否存在
    if(!isDataExists(id))
    {
        QMessageBox::warning(this,"提示","数据不存在!");
        return ;
    }
    //预处理的SQL语句
    QString sql="DELETE FROM customer WHERE id=?";
    QSqlQuery sq;
    sq.prepare(sql);
    sq.addBindValue(ui->spinBoxId->value());
    //执行sql语句(执行的是内部预处理的语句)
    if(sq.exec())
    {
        QMessageBox::information(this,"通知","成功删除一条数据!");
    }else
    {
        QString text=sq.lastError().text();
        QMessageBox::warning(this,"提示",text);
    }
}

void Dialog::updateData()
{
    //如果姓名为空,引导用户输入
    QString name=ui->lineEdit->text();
    if(name=="")
    {
        QMessageBox::warning(this,"提示","请输入姓名:");
        return;
    }
    int id=ui->spinBoxId->value();
    //判断更新数据是否存在
    if(!isDataExists(id))
    {
        QMessageBox::warning(this,"提示","数据不存在!");
        return ;
    }
    double money=ui->doubleSpinBox->value();
    double rate=ui->doubleSpinBoxLv->value();

    //操作类对象
    QSqlQuery sq;
    //预处理的SQL语句
    QString sql="UPDATE customer SET name=?,money=?,rate=? WHERE id=?";
    //预处理
    sq.prepare(sql);
    //绑定
    sq.addBindValue(name);
    sq.addBindValue(money);
    sq.addBindValue(rate);
    sq.addBindValue(id);
    //执行
    if(sq.exec())
    {
        QMessageBox::information(this,"通知","成功修改一条数据!");
    }else
    {
        QString text=sq.lastError().text();
        QMessageBox::warning(this,"提示",text);
    }
}

void Dialog::selectAll()
{
    QString sql="SELECT * FROM customer";
    QSqlQuery sq;
    if(sq.exec(sql))
    {
        //清空上次显示结果
        ui->textBrowser->clear();
        while(sq.next())
        {
            //取出每列数据
            //方式一:按照序号(0,1,2,3...)取出
            QString id=sq.value(0).toString();
            //方式二:按照列名取出
            QString name=sq.value("name").toString();
            QString money=sq.value("money").toString();
            QString rate=sq.value("rate").toString();
            QString text;
            text=text+id.append("-")+name.append("-")+money.append("-")+rate;
            //展示数据
            ui->textBrowser->append(text);
        }
    }else
    {
        QString text=sq.lastError().text();
        QMessageBox::warning(this,"提示",text);
    }
}

bool Dialog::isDataExists(int id)
{
    //查询语句
    QString sql="SELECT * FROM customer WHERE id=?";
    //操作类对象
    QSqlQuery sq;
    //预处理
    sq.prepare(sql);
    //绑定
    sq.addBindValue(id);
    //执行
    sq.exec();
    return sq.next();//判断后面有无数据
}

Guess you like

Origin blog.csdn.net/m0_68672255/article/details/130618194