Qt--数据库的增删改查操作
数据库相关类的使用需要在.pro项目配置文件中增加sql模块。本次使用的相关类有:数据库连接类,表示一个数据库的连接。●QSqlError数据库错误信息类,内部包含了数据库底层传递到Qt中的错误信息。●QSqlQuery数据库操作类,用于执行 SQL语句。
一、简介
1.数据库简介
Qt本身并不包含数据库,但是可以通过Qt操作市面上主流的数据库产品,并且Qt为这些数据库的操作设计了统一的操作接口。
支持的数据库产品有:
Qt使用这些数据库都需要在计算机中分别安装对应的数据库产品,但是由于SQLite数据库本身体积较小,因此Qt中集成了SQLite数据库和对应的驱动程序,可以直接使用。
2.类的简介
数据库相关类的使用需要在.pro项目配置文件中增加sql模块。
本次使用的相关类有:
●QSqlDatabase
数据库连接类,表示一个数据库的连接。
●QSqlError
数据库错误信息类,内部包含了数据库底层传递到Qt中的错误信息。
●QSqlQuery
数据库操作类,用于执行 SQL语句。
二、连接和关闭数据库
相关函数如下:
// 获得一个数据库连接对象
// 参数:数据库的类型,SQLite3数据库对应的类型是"QSQLITE"
// 返回值:数据库连接对象
QSqlDatabase QSqlDatabase::addDatabase(const QString & type) [static]
// 如果使用的是SQLite数据库,此函数表示设置的是数据库文件的名称,数据库文件会在项目的构建目录中生成
// 参数:数据库文件名称,SQLite数据库文件的格式通常是.db或.db3
void QSqlDatabase::setDatabaseName(const QString & name)
// 打开数据库连接
// 返回值是打开连接的结果
bool QSqlDatabase::open()
// 返回上一次数据库出错的错误信息
QSqlError QSqlDatabase::lastError() const
// 返回错误信息的字符串
QString QSqlError::text() const
//关闭数据库连接
//sqlite本质上是文件操作,Qt程序结束时任何打开的文件是会关掉的,但是最好要在程序中关闭连接。
void QSqlDatabase::close()
连接成功后会在构建目录里会生成数据库文件。
三、建表
一个可参考的建表语句(本文设计的是水果管理系统)如下所示:
CREATE TABLE fruit(
id INTEGER PRIMARY KEY,
name TEXT,
loc TEXT,
price REAL);
相关函数如下:
// 执行SQL语句
// 参数:要执行的SQL语句
// 返回值:执行的结果
bool QSqlQuery::exec(const QString & query)
// 返回当前操作类对象的上一个执行错误信息
QSqlError QSqlQuery::lastError() const
建表完成后,可以使用SQLiteSpy程序直接打开.db文件,观察内部的表结构是否与预设一致,检验建表操作是否成功。
四、增删改
插入数据需要先获取用户输入,把用户输入的数据组成对应SQL语句执行。Qt中不建议使用字符串拼接的方式组成最终的SQL语句,因为:
●会降低代码的安全性,可能引发SQL注入问题
●拼接字符串容易出错
Qt中推荐使用SQL预处理+参数绑定的方式,分为三步:
1. 先编写一个预处理的SQL语句,在这个SQL语句中需要参数的位置使用占位符替换,占位符有两种编写方式:
●Oracle风格
占位符使用 :列名
这种风格的缺点是代码编写繁琐,优点是参数绑定时可以乱序。
●ODBC风格
占位符使用英文问号 ?
这种风格的优点是代码编写简单,缺点是参数绑定时必须按照顺序。
// 预处理函数
// 参数为要预处理的SQL语句
// 返回值为预处理的结果
bool QSqlQuery::prepare(const QString & query)
2. 调用函数进行参数绑定,把参数绑定到第一步占位符的位置。
// Oracle风格的参数绑定函数
// 参数1::列名
// 参数2:参数1对应的绑定数据
void QSqlQuery::bindValue(const QString & placeholder,
const QVariant & val)
// ODBC风格的参数绑定函数
// 参数为QVariant类型,表示支持常见的Qt数据类型
void QSqlQuery::addBindValue(const QVariant & val)
3. 执行绑定后的SQL语句。
// 执行之前预处理的SQL语句,注意不要传递参数,如果传递参数,表示执行参数对应的SQL语句
// 返回值:执行的结果
bool QSqlQuery::exec()
插入操作执行后,同样可以通过SQLiteSpy打开数据文件,双击表名可以查询表中内容进行验证。
五、查询
模糊查询使用关键字LIKE配合两个通配符实现:
●%
任意多个(0,1,......,n)字符。
●_
任意一个字符
相关函数如下:
// 尝试获得下个记录的数据,如果成功则移动游标并返回true;如果失败返回false
bool QSqlQuery::next()
// 取得当前游标指向的记录的某一列数据
// 参数:列序号
// 返回值:QVariant类型,可以根据所需转换为对应类型
QVariant QSqlQuery::value(int index) const
// 取得当前游标指向的记录的某一列数据
// 参数:列名
// 返回值:QVariant类型,可以根据所需转换为对应类型
QVariant QSqlQuery::value(const QString & name) const
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QMessageBox>
#include <QButtonGroup>
// 数据库连接类
#include <QSqlDatabase>
#include <QDebug>
// 数据库错误信息类
#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;
void connect2DB(); // 连接到数据库
QSqlDatabase db; // 数据库连接类对象
void createTable(); // 建表
void insertData(); // 插入数据
void deleteData(); // 删除数据
void updateData(); // 更改数据
void selectAll(); // 查询所有数据
bool isDataExists(int); // 判断某个id的数据在不在
void selectLike(); // 模糊查询
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)
{
insertData();
}else if(id == 2)
{
deleteData();
}else if(id == 3)
{
updateData();
}else if(id == 4)
{
selectLike();
}
}
Dialog::~Dialog()
{
//sqlite本质上是文件操作,Qt程序结束时任何打开的文件是会关掉的,但是最好要在程序中关闭连接。
db.close();
delete ui;
}
void Dialog::connect2DB()
{
// 获得数据库连接对象
db = QSqlDatabase::addDatabase("QSQLITE");
// 数据库文件名称
db.setDatabaseName("fruit_management.db");
// 打开连接
if(db.open())
{
qDebug() << "数据库连接成功!";
createTable();
selectAll();
}else
{
// 获得错误信息
QSqlError info = db.lastError();
QString text = info.text();
QMessageBox::critical(this,"错误",text.prepend("连接失败!"));
}
}
void Dialog::createTable()
{
// 建表语句
QString sql = QString("CREATE TABLE fruit(\
id INTEGER PRIMARY KEY,\
name TEXT,\
loc TEXT,\
price REAL);");
sql = "CREATE TABLE fruit(id INTEGER PRIMARY KEY,name TEXT,loc TEXT,price REAL);";
// 数据库操作类对象
QSqlQuery sq;
// 执行SQL语句
if(sq.exec(sql))
{
qDebug() << "建表成功!";
}else
{
// 获得错误信息
QString text = sq.lastError().text();
qDebug() << text.prepend("建表失败!");
}
}
void Dialog::insertData()
{
// 如果名称不输入引导用户输入
QString name = ui->lineEdit->text();
if(name == "")
{
QMessageBox::warning(this,"提示","请输入名称!");
return;
}
int id = ui->spinBox->value();
QString loc = ui->comboBox->currentText();
double price = ui->doubleSpinBox->value();
// 预处理的SQL语句(ODBC风格)
QString sql = "INSERT INTO fruit VALUES(?,?,?,?);";
// 预处理SQL语句
QSqlQuery sq;
sq.prepare(sql);
// 绑定参数(注意顺序)
sq.addBindValue(id);
sq.addBindValue(name);
sq.addBindValue(loc);
sq.addBindValue(price);
// 正式执行SQL语句
if(sq.exec()) // 如果预处理,则不能传递参数!!!
{
selectAll();
QMessageBox::information(this,"通知","数据插入成功!");
}else
{
// 获得错误信息
QString text = sq.lastError().text();
QMessageBox::critical(this,"错误",text.prepend("插入失败!"));
}
}
void Dialog::deleteData()
{
int id = ui->spinBox->value();
// 先看看要删除的数据在不在
if(!isDataExists(id))
{
QMessageBox::information(this,"通知","您要删除的数据不存在");
return;
}
// 预处理的SQL语句(ODBC风格)
QString sql = "DELETE FROM fruit WHERE id=?";
// 预处理SQL语句
QSqlQuery sq;
sq.prepare(sql);
// 绑定参数(注意顺序)
sq.addBindValue(id);
// 正式执行SQL语句
if(sq.exec()) // 如果预处理,则不能传递参数!!!
{
selectAll();
QMessageBox::information(this,"通知","数据删除成功!");
}else
{
// 获得错误信息
QString text = sq.lastError().text();
QMessageBox::critical(this,"错误",text.prepend("删除失败!"));
}
}
void Dialog::updateData()
{
// 如果名称不输入引导用户输入
QString name = ui->lineEdit->text();
if(name == "")
{
QMessageBox::warning(this,"提示","请输入名称!");
return;
}
int id = ui->spinBox->value();
// 先看看要更新的数据在不在
if(!isDataExists(id))
{
QMessageBox::information(this,"通知","您要更新的数据不存在");
return;
}
QString loc = ui->comboBox->currentText();
double price = ui->doubleSpinBox->value();
// 预处理的SQL语句(Oracle风格)
QString sql = "UPDATE fruit SET name=:name,loc=:loc,price=:price WHERE id=:id";
// 预处理SQL语句
QSqlQuery sq;
sq.prepare(sql);
// 绑定参数(注意顺序)
sq.bindValue(":id",id);
sq.bindValue(":name",name);
sq.bindValue(":loc",loc);
sq.bindValue(":price",price);
// 正式执行SQL语句
if(sq.exec()) // 如果预处理,则不能传递参数!!!
{
selectAll();
QMessageBox::information(this,"通知","数据更新成功!");
}else
{
// 获得错误信息
QString text = sq.lastError().text();
QMessageBox::critical(this,"错误",text.prepend("更新失败!"));
}
}
void Dialog::selectAll()
{
QString sql = "SELECT * FROM fruit";
// 数据库操作类对象
QSqlQuery sq;
// 执行SQL语句
if(sq.exec(sql))
{
qDebug() << "查询成功!";
// 清空显示
ui->textBrowser->clear();
// 循环取出每条记录的数据
while(sq.next()) // 向后移动
{
// 获得各列数据
QString id = sq.value(0).toString();
QString name = sq.value("name").toString();
QString loc = sq.value(2).toString();
QString price = sq.value(3).toString();
// 拼接
QString text = id.append(" ")+name.append(" ")+
loc.append(" ") + price;
// 拼接并显示
ui->textBrowser->append(text);
}
}else
{
// 获得错误信息
QString text = sq.lastError().text();
qDebug() << text.prepend("查询失败!");
}
}
bool Dialog::isDataExists(int id)
{
// 偶尔用一把字符串拼接
QString sql = "SELECT * FROM fruit WHERE id=";
sql.append(QString::number(id));
// 数据库操作类对象
QSqlQuery sq;
// 执行SQL语句
if(sq.exec(sql))
{
qDebug() << "查询成功!";
return sq.next();
}else
{
// 获得错误信息
QString text = sq.lastError().text();
qDebug() << text.prepend("查询失败!");
return false;
}
}
void Dialog::selectLike()
{
// 如果名称不输入引导用户输入
QString name = ui->lineEdit->text();
if(name == "")
{
QMessageBox::warning(this,"提示","请输入名称!");
return;
}
// ODBC风格的预处理语句
QString sql = "SELECT * FROM fruit WHERE name LIKE ?";
// 预处理
QSqlQuery sq;
sq.prepare(sql);
// 绑定参数
sq.addBindValue(name.prepend("%").append("%")); // 模糊查询
// 正式执行
// 执行SQL语句
if(sq.exec())
{
qDebug() << "查询成功!";
// 清空显示
ui->textBrowser->clear();
// 循环取出每条记录的数据
while(sq.next()) // 向后移动
{
// 获得各列数据
QString id = sq.value(0).toString();
QString name = sq.value("name").toString();
QString loc = sq.value(2).toString();
QString price = sq.value(3).toString();
// 拼接
QString text = id.append(" ")+name.append(" ")+
loc.append(" ") + price;
// 拼接并显示
ui->textBrowser->append(text);
}
}else
{
// 获得错误信息
QString text = sq.lastError().text();
qDebug() << text.prepend("查询失败!");
}
}
dialog.ui
更多推荐
所有评论(0)