当前位置:   article > 正文

c++ Qt 数据库操作

c++ Qt 数据库操作

1、准备工作

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

Qt支持以下数据库类型:

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

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

  • QSqlDatabase

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

  • QSqlQuery

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

  • QSqlError

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

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

2、连接数据库

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

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

  1. // 获得一个数据库连接对象
  2. // 参数为数据库类型,详见本章第一节表格(区分大小写)
  3. // 返回值为连接对象
  4. #include <QSqlDatabase>
  5. QSqlDatabase QSqlDatabase:: addDatabase(const QString & type)[static]

2)设置数据库名称

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

3)打开数据库连接

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

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

错误信息类为QSqlError

  1. // 返回上一次的错误信息封装类
  2. #include <QSqlError>
  3. QSqlError QSqlDatabase:: lastError() const

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

  1. // 从QSqlError对象中提取错误信息文本
  2. #include <QSqlError>
  3. QString QSqlError:: text() const

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

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

7)关闭数据库连接

  1. // 关闭数据库连接
  2. void QSqlDatabase:: close()

dialog.cpp

  1. #include "dialog.h"
  2. #include "ui_dialog.h"
  3. Dialog::Dialog(QWidget *parent) :
  4.     QDialog(parent),
  5.     ui(new Ui::Dialog)
  6. {
  7.     ui->setupUi(this);
  8.     //创建按钮组
  9.     group = new QButtonGroup(this);
  10.     //添加按钮对象
  11.     group->addButton(ui->pushButtonInsert,1);
  12.     group->addButton(ui->pushButtonDelete,2);
  13.     group->addButton(ui->pushButtonUpdate,3);
  14.     group->addButton(ui->pushButtonSelect,4);
  15.     //按钮组连接
  16. connect(group,SIGNAL(buttonClicked(int)),this,SLOT(btnClickedSlots(int)));
  17.     connectD2B();
  18. }
  19. Dialog::~Dialog()
  20. {
  21.     //检查数据库状态
  22.     if(db.isOpen())
  23.     {
  24.         //关闭数据库连接
  25.         db.close();
  26.     }
  27.     delete ui;
  28. }
  29. //连接数据库
  30. void Dialog::connectD2B()
  31. {
  32.     //获取数据库连接对象
  33.     db = QSqlDatabase::addDatabase("QSQLITE");
  34.     //设置数据库名称
  35.     db.setDatabaseName("book_management.db");
  36.     //打开数据库连接
  37.     bool ret = db.open();
  38.     if(ret == true)
  39.     {
  40.         qDebug()<<"打开成功";
  41.     }
  42.     else
  43.     {
  44.         qDebug()<<"打开失败";
  45.         //返回最近错误信息封装类
  46.         QSqlError errorInfo = db.lastError();
  47.         //从错误信息类提取错误信息
  48.         QString text = errorInfo.text();
  49.         //弹窗显示错误信息
  50.         QMessageBox::critical(this,"错误",text);
  51.     }
  52. }
  53. void Dialog::btnClickedSlots(int id)
  54. {
  55.     if(id == 1)
  56.     {
  57.         qDebug()<<"增加";
  58.     }
  59.     else if(id == 2)
  60.     {
  61.         qDebug()<<"删除";
  62.     }
  63.     else if(id == 3)
  64.     {
  65.         qDebug()<<"修改";
  66.     }
  67.     else if(id == 4)
  68.     {
  69.         qDebug()<<"查询";
  70.     }
  71.     else
  72.     {
  73.         qDebug()<<"错误";
  74.     }
  75. }

3、创建表

建表语句(SQL语句):

  1. //表名   id设置为主键 名字文本 价格实数 作者文本
  2. CREATE TABLE book(id INTEGER PRIMARY KEY,name TEXT,price REAL,author TEXT);

  1. CREATE TABLE book(
  2.     id INTEGER PRIMARY KEY,
  3.     name TEXT,
  4.     price REAL,
  5.     author TEXT
  6. );

查看建表是否成功

  1. // 执行SQL语句
  2. // 参数为SQL语句内容
  3. // 返回值为执行的结果,只关心是否成功,其他不管
  4. bool QSqlQuery:: exec(const QString & query)

错误信息

  1. // 与本章第2节的同名函数用法完全一样
  2. QSqlError QSqlQuery::lastError() const

一个操作SQLite的可视化软件

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

  1. //创建表(建表)
  2. void Dialog::creatTable()
  3. {
  4.     //方法1       //表名   id设置为整形主键 名字文本 价格实数 作者文本
  5.      QString sql ="CREATE TABLE book(id INTEGER PRIMARY KEY,name TEXT,price REAL,author TEXT);";
  6.     //方法2
  7.     sql = QString("CREATE TABLE book(\//表名 \
  8.                     id INTEGER PRIMARY KEY,\//id设置为整形主键\
  9.                     name TEXT,\//名字 文本\
  10.                     price REAL,\//价格  实数\
  11.                     author TEXT);\//作者     文本\
  12.                     ");   
  13.  //创建数据库操作
  14.     QSqlQuery sq;
  15.     //执行SQL语句,并检查是否创建表成功
  16.     if(sq.exec(sql))
  17.     {
  18.         qDebug()<<"建表成功";
  19.     }
  20.     else// 建表失败,注意:建表成功或失败都很正常,如果要建的表已经存在,就会建表失败
  21.     {
  22.         //获取错误信息封装类
  23.         QSqlError errorInfo = sq.lastError();
  24.         //从错误信息封装类获取错误信息
  25.         QString text = errorInfo.text();
  26.         qDebug()<<"建表失败"<<text;
  27.     }
  28. }

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内部。

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

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

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

增加操作

  1. void Dialog::insertData()
  2. {
  3. QString name = ui->lineEdit->text();
  4. if(name == "")
  5. {
  6. QMessageBox::warning(this,"提示","请输入书名");
  7. return;
  8. }
  9. QString author = ui->lineEditAuthor->text();
  10. if(author == "")
  11. {
  12. QMessageBox::warning(this,"提示","请输入作者名");
  13. return;
  14. }
  15.     int id = ui->spinBox->value();
  16.     double price = ui->doubleSpinBox->value();
  17. // 预处理的SQL语句
  18. QString sql = "INSERT INTO book VALUES(?,?,?,?);";
  19. // 预处理
  20. QSqlQuery sq;
  21.     sq.prepare(sql);
  22. // 绑定数据
  23.     sq.addBindValue(id);
  24.     sq.addBindValue(name);
  25.     sq.addBindValue(price);
  26.     sq.addBindValue(author);·
  27. // 执行绑定好的SQL语句,并检查执行状态
  28. if(sq.exec())
  29. {
  30. QMessageBox::information(this,"通知","数据插入成功");
  31. }
  32. else
  33. {
  34. // 获取错误信息封装类
  35. QSqlError info = sq.lastError();
  36. QString text = info.text();
  37. QMessageBox::warning(this,"警告","数据插入失败");
  38. }
  39. }

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

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

删除操作

  1. // 删除, 按照id删除
  2. void Dialog::deleteData()
  3. {
  4.     int id = ui->spinBox->value();
  5. // 查询表中id是否存在
  6. // TODO --
  7. // 预处理的SQL语句
  8. QString sql = "DELETE FROM book WHERE id=?";
  9. QSqlQuery sq;
  10.     sq.prepare(sql); // 预处理
  11. // 绑定参数
  12.     sq.addBindValue(id);
  13. // 执行绑定后SQL语句
  14. if(sq.exec())
  15. {
  16. QMessageBox::information(this,"通知","数据删除成功");
  17. }
  18. else
  19. {
  20. // 获得错误信息封装类
  21. QSqlError info = sq.lastError();
  22. QString text = info.text();
  23. QMessageBox::critical(this,"错误",text);
  24. }
  25. }

更改操作

  1. //按编号修改数据
  2. void Dialog::updateDate()
  3. {
  4.     //获得用户输入的数据,(全部获得)
  5.     QString name = ui->lineEdit->text();
  6.     if(name == "")
  7.     {
  8.         QMessageBox::warning(this,"提示","请输入书名");
  9.         return;
  10.     }
  11.     QString author = ui->lineEditAuthor->text();
  12.     if(author == "")
  13.     {
  14.         QMessageBox::warning(this,"提示","请输入作者名");
  15.         return;
  16.     }
  17.     int id = ui->spinBox->value();
  18.     double price = ui->doubleSpinBox->value();
  19.     //判断ID在数据库中是否存在
  20.     //预处理语句(oracle风格),不需要注意数据顺序
  21.     QString sql = "UPDATE book SET name=:name,price=:price,author=:author WHERE id=:id";
  22.     //预处理
  23.     QSqlQuery sq;
  24.     sq.prepare(sql);
  25.     //绑定参数
  26.     sq.bindValue(":id",id);
  27.     sq.bindValue(":name",name);
  28.     sq.bindValue(":price",price);
  29.     sq.bindValue(":author",author);
  30.     //执行绑定后的SQL语句
  31.     if(sq.exec())
  32.     {
  33.         QMessageBox::information(this,"提示","数据更改成功");
  34.         return;
  35.     }
  36.     else
  37.     {
  38.         //获取错误信息封装
  39.         QSqlError info = sq.lastError();
  40.         QString text = info.text();
  41.         QMessageBox::critical(this,"错误",text);
  42.     }
  43. }

5、查询

5.1 全查

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

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

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

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

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

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

  1. void Dialog::selectAll()
  2. {
  3.     //清空textBrowser
  4.     ui->textBrowser->clear();
  5.     QString sql = "SELECT * FROM book";
  6.     QSqlQuery sq;
  7.     if(sq.exec(sql))
  8.     {
  9.         while(sq.next())
  10.         {
  11.             //取出一条记录中的每个字段值
  12.             QString id = sq.value(0).toString();
  13.             QString name = sq.value(1).toString();
  14.             QString price = sq.value("price").toString();
  15.             QString author = sq.value("author").toString();
  16.             //显示
  17.             QString text = id.append("-")+name.append("-")+price.append("-")+author;
  18.             ui->textBrowser->append(text);
  19.         }
  20.     }
  21. }

查看id是否存在

  1. bool Dialog::isDateExists(int id)
  2. {
  3.     QString idText = QString::number(id);
  4.     QString sql = "SELECT * FROM book WHERE id=";
  5.     sql.append(idText);
  6.     QSqlQuery sq;
  7.     if(sq.exec(sql))
  8.     {
  9.         return sq.next();
  10.     }
  11.     else
  12.     {
  13.         return false;
  14.     }
  15. }

5.2模糊查询

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

通配符

  • %

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

  • _

任意一个字符

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

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

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

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

dialog.cpp

  1. //模糊查询
  2. void Dialog::selectLike()
  3. {
  4.     //获取要查询的内容
  5.     QString name = ui->lineEdit->text();
  6.     if(name == "")
  7.     {
  8.         QMessageBox::warning(this,"提示","请输入书名");
  9.         return;
  10.     }
  11.     else
  12.     {
  13.         //预处理
  14.         QString sql = "SELECT * FROM book WHERE name LIKE ?";
  15.         QSqlQuery sq;
  16.         sq.prepare(sql);
  17.         //SQL语句处理,%name%
  18.         sq.addBindValue(name.prepend("%").append("%"));
  19.         if(sq.exec())
  20.         {
  21.             //添加状态位置,检查是否查询到结果
  22.             bool reState = true;
  23.             //清空上次查询内容
  24.             ui->textBrowser->clear();
  25.             while(sq.next())
  26.             {
  27.                 //数据库数据遍历
  28.                 QString id = sq.value(0).toString();
  29.                 QString name = sq.value(1).toString();
  30.                 QString price = sq.value(2).toString();
  31.                 QString author = sq.value(3).toString();
  32.                 //显示
  33.                 QString text = id.append("-")+name.append("-")+price.append("-")+author;
  34.                 ui->textBrowser->append(text);
  35.                 reState =false;
  36.             }
  37.             //查询结果判断
  38.             if(reState)
  39.             {
  40.                 QMessageBox::information(this,"提示","没有相关结果");
  41.                 return;
  42.             }
  43.         }
  44.         else
  45.         {
  46.             //错误信息弹窗
  47.             QSqlError err = sq.lastError();
  48.             QString text = err.text();
  49.             QMessageBox::critical(this,"错误",text);
  50.         }
  51.     }
  52. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/112766
推荐阅读
相关标签
  

闽ICP备14008679号