目录
1. Qt数据库简介
2. 连接与关闭
3. 建表
dialog.h
dialog.cpp
dialog.ui
4. 增删改
1.添加数据
dialog.h
dialog.cpp
2.删除数据
dialog.h
dialog.cpp
3.修改数据
dialog.h
dialog.cpp
5. 查询
dialog.h
dialog.cpp
判断数据是否存在
dialog.h
dialog.cpp
1. Qt数据库简介
Qt只是作为媒介去操作数据库,本身不具备数据库的功能,因此除了Qt以外,还需要在计算机中安装对应的数据库软件,但是由于SQLite数据库比较轻巧,因此Qt集成了SQLite数据库,此数据库是嵌入式中最常用的数据库。
实际上Qt支持以下类型的数据库产品:
在Qt项目中使用数据库必须在.pro项目配置文件中增加sql模块。
2. 连接与关闭
主要使用到的类是数据库连接类QSqlDatabase和数据库错误信息类QSqlError,涉及的函数有:
// 获得一个基于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()
连接成功后会生成数据库文件。
3. 建表
QSqlQuery主要用于执行SQL语句,相关函数如下。
// 执行SQL语句
// 参数是要执行的SQL语句
// 返回值是语句本身执行的结果,并不是数据操作的结果
bool QSqlQuery::exec(const QString & query)
// 用法与之前的同名函数完全相同
QSqlError QSqlQuery::lastError() const
参考建表语句:
CREATE TABLE customer(id INTEGER PRIMARY KEY,name TEXT,money REAL,rate REAL);
建表成功后,可以直接到构建目录中使用SQLiteSpy工具打开.db文件验证是否建表成功。
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. 增删改
增删改的操作方法比较相似,需要注意是不要使用拼接的方式创建带参数的SQL语句,原因有:
- 拼接复杂,容易出错
- 容易引发SQL注入的安全问题
Qt使用占位符替换的方式“拼接”SQL语句,占位符替换有两种方式:
- 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.添加数据
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.删除数据
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.修改数据
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. 查询
查询与迭代器指针的工作原理类似,相关函数如下。
// 取出结果中的下一个记录,如果没有下一个记录则返回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);
}
}
判断数据是否存在
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();//判断后面有无数据
}