目录

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

连接成功后会生成数据库文件。

3.建表

QSqlQuery主要用于执行SQL语句,相关函数如下。

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

CREATE TABLEcustomer(idINTEGER PRIMARY KEY,nameTEXT,moneyREAL,rateREAL);

建表成功后,可以直接到构建目录中使用SQLiteSpy工具打开.db文件验证是否建表成功。

dialog.h

#ifndef DIALOG_H#define DIALOG_H#include#include#include#include#include#includenamespace Ui {class Dialog;}class Dialog : public QDialog{Q_OBJECTpublic: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语句,占位符替换有两种方式:

  • ODBCstyle(?)
  • Oraclestylecolon-name
//预处理带有占位符的SQL语句//参数为预处理的SQL语句//返回值是预处理的结果boolQSqlQuery::prepare(constQString&query)//添加绑定数据//参数为要绑定的数据,各种类型直接传递即可,传递的顺序要按照?的顺序voidQSqlQuery::addBindValue(constQVariant&val)//执行预处理的SQL语句//语句本身是否成功执行boolQSqlQuery::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通知","成功删除一条数据!");}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=" />

5.查询

查询与迭代器指针的工作原理类似,相关函数如下。

//取出结果中的下一个记录,如果没有下一个记录则返回falseboolQSqlQuery::next()//按照列序号取出对应的列数据//参数是列序号,从0开始//返回值是取出的数据,支持各种常见类型的转换QVariantQSqlQuery::value(int index)const//按照列名取出对应的列数据//参数是列名//返回值是取出的数据,支持各种常见类型的转换QVariantQSqlQuery::value(constQString&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()<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(" />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();//判断后面有无数据}