1、准备工作

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

Qt支持以下数据库类型:

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

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

QSqlDatabase

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

QSqlQuery

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

QSqlError

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

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

2、连接数据库

主要通过QSqlDatabase类进行连接。相关函数:

1)获得一个数据库连接对象

// 获得一个数据库连接对象

// 参数为数据库类型,详见本章第一节表格(区分大小写)

// 返回值为连接对象

#include 

QSqlDatabase QSqlDatabase:: addDatabase(const QString & type)[static]

2)设置数据库名称

// 设置数据库名称

// 参数因不同的数据库表示不同的涵义。对于SQLite,此函数表示数据库文件名。此文件会在项目中构建目录中生成

void QSqlDatabase:: setDatabaseName(const QString & name)

3)打开数据库连接

// 打开数据库连接

// 返回值为连接打开的结果,如果打开失败,可以通过lastError函数获取错误信息

bool QSqlDatabase:: open()

4)返回上一次的错误信息封装类

错误信息类为QSqlError

// 返回上一次的错误信息封装类

#include 

QSqlError QSqlDatabase:: lastError() const

5)从QSqlError对象中提取错误信息文本

// 从QSqlError对象中提取错误信息文本

#include 

QString QSqlError:: text() const

6)返回数据库连接的打开状态

// 返回数据库连接的打开状态

bool QSqlDatabase:: isOpen() const

7)关闭数据库连接

// 关闭数据库连接

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(btnClickedSlots(int)));

    connectD2B();

}

Dialog::~Dialog()

{

    //检查数据库状态

    if(db.isOpen())

    {

        //关闭数据库连接

        db.close();

    }

    delete ui;

}

//连接数据库

void Dialog::connectD2B()

{

    //获取数据库连接对象

    db = QSqlDatabase::addDatabase("QSQLITE");

    //设置数据库名称

    db.setDatabaseName("book_management.db");

    //打开数据库连接

    bool ret = db.open();

    if(ret == true)

    {

        qDebug()<<"打开成功";

    }

    else

    {

        qDebug()<<"打开失败";

        //返回最近错误信息封装类

        QSqlError errorInfo = db.lastError();

        //从错误信息类提取错误信息

        QString text = errorInfo.text();

        //弹窗显示错误信息

        QMessageBox::critical(this,"错误",text);

    }

}

void Dialog::btnClickedSlots(int id)

{

    if(id == 1)

    {

        qDebug()<<"增加";

    }

    else if(id == 2)

    {

        qDebug()<<"删除";

    }

    else if(id == 3)

    {

        qDebug()<<"修改";

    }

    else if(id == 4)

    {

        qDebug()<<"查询";

    }

    else

    {

        qDebug()<<"错误";

    }

}

3、创建表

建表语句(SQL语句):

//表名   id设置为主键 名字文本 价格实数 作者文本

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

);

查看建表是否成功

// 执行SQL语句

// 参数为SQL语句内容

// 返回值为执行的结果,只关心是否成功,其他不管

bool QSqlQuery:: exec(const QString & query)

错误信息

// 与本章第2节的同名函数用法完全一样

QSqlError QSqlQuery::lastError() const

一个操作SQLite的可视化软件

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

//创建表(建表)

void Dialog::creatTable()

{

    //方法1       //表名   id设置为整形主键 名字文本 价格实数 作者文本

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

    //方法2

    sql = QString("CREATE TABLE book(\//表名 \

                    id INTEGER PRIMARY KEY,\//id设置为整形主键\

                    name TEXT,\//名字 文本\

                    price REAL,\//价格  实数\

                    author TEXT);\//作者     文本\

                    ");   

 //创建数据库操作

    QSqlQuery sq;

    //执行SQL语句,并检查是否创建表成功

    if(sq.exec(sql))

    {

        qDebug()<<"建表成功";

    }

    else// 建表失败,注意:建表成功或失败都很正常,如果要建的表已经存在,就会建表失败

    {

        //获取错误信息封装类

        QSqlError errorInfo = sq.lastError();

        //从错误信息封装类获取错误信息

        QString text = errorInfo.text();

        qDebug()<<"建表失败"<

    }

}

4、增删改

增删改都需要先录入用户输入,然后把用户输入的数据组装成SQL语句,最后执行。

组装SQL语句有两种方式:

字符串拼接

这种方式实现简单,但是容易拼接错误,且安全性较低。

预处理+占位符

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

占位符有两种表示风格:

Oracle风格

使用:字段的格式

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

ODBC风格

使用?的格式

INSERT INTO book VALUES(?,?,?,?);

预处理SQL语句,此时SQL语句并没有执行,只是送入到了Qt内部。

// 预处理SQL语句,此时SQL语句并没有执行,只是送入到了Qt内部。

// 参数为预处理的SQL语句

// 返回值预处理的结果

bool QSqlQuery:: prepare(const QString & query)

绑定ODBC风格的占位符参数,绑定的时候一定要注意顺序。

// 绑定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 info = sq.lastError();

QString text = info.text();

QMessageBox::warning(this,"警告","数据插入失败");

}

}

绑定Oracle风格的占位符参数,绑定可以乱序

// 绑定Oracle风格的占位符参数,绑定可以乱序

// 参数1:占位符

// 参数2:要绑定的数据

void QSqlQuery:: bindValue(const QString & placeholder, const QVariant & val)

删除操作

// 删除, 按照id删除

void Dialog::deleteData()

{

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

// 查询表中id是否存在

// TODO --

// 预处理的SQL语句

QString sql = "DELETE FROM book WHERE id=?";

QSqlQuery sq;

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

// 绑定参数

    sq.addBindValue(id);

// 执行绑定后SQL语句

if(sq.exec())

{

QMessageBox::information(this,"通知","数据删除成功");

}

else

{

// 获得错误信息封装类

QSqlError info = sq.lastError();

QString text = info.text();

QMessageBox::critical(this,"错误",text);

}

}

更改操作

//按编号修改数据

void Dialog::updateDate()

{

    //获得用户输入的数据,(全部获得)

    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在数据库中是否存在

    //预处理语句(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(":name",name);

    sq.bindValue(":price",price);

    sq.bindValue(":author",author);

    //执行绑定后的SQL语句

    if(sq.exec())

    {

        QMessageBox::information(this,"提示","数据更改成功");

        return;

    }

    else

    {

        //获取错误信息封装

        QSqlError info = sq.lastError();

        QString text = info.text();

        QMessageBox::critical(this,"错误",text);

    }

}

5、查询

5.1 全查

1)判断查询结果有无数据,如果有数据则移动游标取出,没有返回false

// 判断查询结果有无数据,如果有数据则移动游标取出,没有返回false

bool QSqlQuery:: next()

2)按照字段序号取出对应的值,序号从0开始

// 按照字段序号取出对应的值,序号从0开始

// 返回值QVariant类型,可以根据需要直接转换为所需要类型

QVariant QSqlQuery:: value(int index) const

3)按照字段名称取出对应的值

// 按照字段名称取出对应的值

// 返回值QVariant类型,可以根据需要直接转换为所需要类型

QVariant QSqlQuery:: value(const QString & name) const

void Dialog::selectAll()

{

    //清空textBrowser

    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);

        }

    }

}

查看id是否存在

bool Dialog::isDateExists(int id)

{

    QString idText = QString::number(id);

    QString sql = "SELECT * FROM book WHERE id=";

    sql.append(idText);

    QSqlQuery sq;

    if(sq.exec(sql))

    {

        return sq.next();

    }

    else

    {

        return false;

    }

}

5.2模糊查询

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

通配符

%

任意多个(0、1、2、3........n)字符

_

任意一个字符

【例子】查找‘瑞’ 字辈的信息

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

【例子】查找姓名中包含“瑞”这个字的人员信息。

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

dialog.cpp

//模糊查询

void Dialog::selectLike()

{

    //获取要查询的内容

    QString name = ui->lineEdit->text();

    if(name == "")

    {

        QMessageBox::warning(this,"提示","请输入书名");

        return;

    }

    else

    {

        //预处理

        QString sql = "SELECT * FROM book WHERE name LIKE ?";

        QSqlQuery sq;

        sq.prepare(sql);

        //SQL语句处理,%name%

        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,"提示","没有相关结果");

                return;

            }

        }

        else

        {

            //错误信息弹窗

            QSqlError err = sq.lastError();

            QString text = err.text();

            QMessageBox::critical(this,"错误",text);

        }

    }

}

精彩内容

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。