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); } } } 精彩内容
发表评论