Qt使用sqlite数据库及项目实战

激昂~逐流 2024-10-01 16:35:01 阅读 72

一.sqlite使用介绍

在Qt中使用SQLite数据库非常简单,SQLite是一个轻量级的嵌入式数据库,不需要单独的数据库服务器,完全使用本地文件来存储数据。

当在Qt中使用SQLite数据库时,需要涉及到一些SQL语句以及Qt中的相关函数,接下来我将从头开始介绍所有涉及的语句以及相应的解释。

1. 连接到数据库:addDatabase

在Qt中,你可以使用QSqlDatabase来连接数据库。首先需要添加数据库类型,然后指定数据库的名称:

<code>QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");

db.setDatabaseName("mydatabase.db");

if(!db.open()) {

qDebug() << "无法连接到数据库";

return;

}

在这段代码中,我们首先创建了一个名为mydatabase.db的SQLite数据库,然后通过open()函数来打开数据库连接。如果连接失败,将会输出错误信息。

2. 创建表:CREATE TABLE

一般来说,你需要在数据库中创建表来存储数据。这可以通过执行CREATE TABLE语句来实现:

QSqlQuery query;

query.exec("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)");

这里我们使用exec()函数执行SQL语句,创建了一个名为users的表,包含id、name和age三个列。

3. 插入数据:INSERT

当需要在表中插入新的数据时,可以使用SQL的INSERT INTO语句。在Qt中,可以使用QSqlQuery对象的prepare()和bindValue()函数来执行预处理插入语句:

常规的数据库插入语句

INSERT into users(id,name,age)VALUES(111,"name",12)

Qt中

QString name = "Alice";

int age = 25;

QSqlQuery query;

query.prepare("INSERT INTO users (name, age) VALUES (:name, :age)");

query.bindValue(":name", name);

query.bindValue(":age", age);

if(!query.exec()) {

qDebug() << "插入数据失败:" << query.lastError().text();

}

prepare和bindValue函数介绍

当在Qt中进行数据库操作时,使用query.prepare()和query.bindValue()方法可以帮助你执行预处理SQL语句并绑定参数的值。这两个方法在插入操作中起到了重要作用,下面我将详细介绍它们的功能和作用:

query.prepare():

在Qt中,query.prepare()方法用于准备要执行的SQL语句。它的主要作用是将SQL语句中的参数部分用占位符(如:variable)代替,从而形成一个预处理的SQL语句。通过这种方式,可以避免SQL注入攻击,并提高程序的安全性。

例如,在插入操作中,你可能会使用INSERT INTO table_name (column1, column2, …) VALUES (:value1, :value2, …)这样的SQL语句,其中的:value1、:value2是占位符,用于将实际的数值动态地填充进去。使用query.prepare()方法可以将这个SQL语句准备好,等待绑定参数值。

query.bindValue():

一旦调用了query.prepare()方法准备好了SQL语句,接下来就可以使用query.bindValue()方法为每个占位符绑定具体的数值。这个方法的作用是设置预处理语句中的占位符的值,从而将真实的数据插入到SQL语句中。

例如,在前面的插入操作示例中,我们对name和age这两个占位符使用了query.bindValue()方法,将实际的name和age变量的值绑定到了这两个占位符上。

使用query.bindValue()方法可以方便地将变量的值插入到SQL语句中,同时还可以防止数据类型转换错误和SQL注入攻击。

综上所述,query.prepare()方法用于准备预处理SQL语句,并替换其中的占位符,而query.bindValue()方法则用于将实际的数值绑定到这些占位符上,从而完成对数据库的插入操作。这两个方法的结合使用可以简化代码编写,同时提高程序的安全性和可维护性。

4. 查询数据:SELECT

查询数据最常见的方式是使用SELECT语句。在Qt中,我们可以通过exec()函数执行SELECT语句,并使用next()函数来逐行获取结果:

QSqlQuery query;

query.exec("SELECT * FROM users");

while(query.next()) {

int id = query.value(0).toInt();

QString name = query.value(1).toString();

int age = query.value(2).toInt();

qDebug() << "ID:" << id << " Name:" << name << " Age:" << age;

}

这段代码遍历了users表中的所有行,并输出每一行的ID、名称和年龄。

query.next介绍

在Qt中,query.next()方法用于遍历查询结果集中的下一行数据。当执行SELECT查询语句并通过exec()方法获取结果集后,可以使用query.next()方法逐行访问查询结果中的数据。

每次调用query.next()方法,会将查询结果集中的指针移到下一行数据。如果存在下一行数据,则该方法返回true,并允许获取下一行数据;如果不存在下一行数据,则返回false,表示已经遍历完所有结果。

一般来说,可以在一个循环中使用query.next()方法来遍历整个查询结果集,逐行获取数据并进行相应的处理。在循环中,通常会结合query.value()方法用于获取特定列的值。

5. 更新数据:UPDATE

在 Qt 中使用 SQLite 实现更新(修改)数据库操作可以通过执行 SQL UPDATE 语句来实现。下面是一个简单的示例代码,演示了如何使用 Qt 和 SQLite 执行更新操作:

#include <QCoreApplication>

#include <QSqlDatabase>

#include <QSqlQuery>

#include <QSqlError>

#include <QDebug>

int main(int argc, char *argv[]) {

QCoreApplication app(argc, argv);

// 连接到SQLite数据库

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");

db.setDatabaseName("database.db"); // 指定SQLite数据库文件

if (!db.open()) {

qDebug() << "Error: Unable to connect to database.";

return 1;

}

// 执行 UPDATE 操作

QSqlQuery query;

query.prepare("UPDATE student SET name = :newName WHERE id = :id");

query.bindValue(":newName", "New Name"); // 设置要更新的新名称

query.bindValue(":id", 1); // 设置要更新的记录的 ID

if (query.exec()) {

qDebug() << "Update successful";

} else {

qDebug() << "Update failed:" << query.lastError().text();

}

return app.exec();

}

6. 删除数据:DELETE

使用 QSqlQuery 类删除数据:

QSqlQuery query;

query.prepare("DELETE FROM your_table WHERE condition = :condition"); // 设置删除语句

query.bindValue(":condition", value); // 绑定条件值

bool success = query.exec(); // 执行删除操作

if(success) {

// 删除成功

} else {

// 删除失败,处理错误

qDebug() << "Error:" << query.lastError().text();

}

7. 更新数据库中的数据:submitAll

这是对模型进行了修改,将数据提交回数据库中,以保持同步。

// 创建 QSqlTableModel 并设置数据库表

QSqlTableModel model;

model.setTable("student");

model.select(); // 从数据库中选择数据

// 创建 QTableView 并设置模型

QTableView tableView;

tableView.setModel(&model);

// 创建一个按钮,当点击时提交更新

QPushButton updateButton("Update Database");

QObject::connect(&updateButton, &QPushButton::clicked, [&model](){

if (model.submitAll()) {

qDebug() << "Database update successful";

} else {

qDebug() << "Database update failed:" << model.lastError().text();

}

});

model.submitAll介绍

QSqlTableModel 中的 submitAll() 函数是用于将对模型数据的更改提交到数据库中的方法。当您在 QTableView 中对数据进行了修改、插入或删除等操作后,调用 submitAll() 函数可将这些更改应用到数据库中。

submitAll() 函数会执行以下操作:

检查模型中的每一行,如果该行的状态为 Inserted、Deleted 或 Modified,则将对应的更改提交到数据库中。如果提交成功,会返回 true;如果提交失败,会返回 false。您可以通过检查返回值来确定提交是否成功。如果提交失败,您可以调用 model.lastError().text() 来获取详细的错误信息。这将返回一个描述在提交过程中发生的错误的字符串。

在模型视图的结构中,对model是临时修改数据的中转站。

8. 更新QSqlQueryModel中的数据

QSqlQueryModel 是一个只读模型,无法直接编辑数据,因此更新数据的方式不同于可编辑的模型,比如 QSqlTableModel。如果您想要更新 QSqlQueryModel 中的数据,可以重新执行查询语句或者重新设置查询。

以下是更新 QSqlQueryModel 中数据的一种常见方法:

重新执行查询语句:您可以重新设置 QSqlQueryModel 的查询语句,然后调用 setQuery() 方法重新执行查询。这将重新从数据库中读取数据并更新模型中的数据。

QSqlQueryModel model;

model.setQuery("SELECT * FROM your_table");

使用 clear() 方法清空数据:如果需要清空 QSqlQueryModel 中的数据,您可以调用 clear() 方法。清空数据后,您可以重新设置查询或数据源,从而实现更新。

model.clear();

需要注意的是,QSqlQueryModel 是一个只读模型,不支持直接编辑数据,如果您需要在界面上进行编辑和更新操作,可以考虑使用 QSqlTableModel 或自定义的 QAbstractTableModel。

9. 对指定列进行排序

这是对模型进行排序

// 创建 QSqlQueryModel 并设置查询语句

QSqlQueryModel *queryModel = new QSqlQueryModel;

queryModel->setQuery("SELECT * FROM your_table");

// 创建 QSortFilterProxyModel 并设置源模型为 QSqlQueryModel

QSortFilterProxyModel *sortModel = new QSortFilterProxyModel(this);

sortModel->setSourceModel(queryModel);

// 设置排序的列索引

int sortColumn = 1; // 假设要按第1列排序

sortModel->sort(sortColumn, Qt::AscendingOrder); // 进行升序排序

// 将排序后的模型设置给视图

yourTableView->setModel(sortModel);

对数据库进行排序

-- 以id列的升序方式进行排序

SELECT id, name, age

FROM your_table

ORDER BY id ASC;

SELECT id ,name ,score FROM student ORDER BY id DESC

//对模型中的数据进行排序

model->setQuery("SELECT id, name, score FROM student ORDER BY id DESC");

二.成绩管理系统实战

1. 项目效果

在这里插入图片描述

项目说明:底层存储数据用的是sqlite,界面展示数据用的是tableView和QSqlQueryModel的视图模型模式。

2. 项目源码:

类定义

<code>#ifndef STUDENTDLG_H

#define STUDENTDLG_H

#include <QDialog>

#include <QSqlDatabase> // 专用于连接、创建数据

#include <QSqlQuery> // 专用于DML(数据操纵语言)、DDL(数据定义语言)

#include <QSqlQueryModel>//数据库模型,用来和tableview关联

#include <QSqlError>

#include <QDebug>

#include <QMessageBox>

QT_BEGIN_NAMESPACE

namespace Ui { class StudentDlg; }

QT_END_NAMESPACE

class StudentDlg : public QDialog

{

Q_OBJECT

public:

StudentDlg(QWidget *parent = nullptr);

~StudentDlg();

private slots:

void on_pushButtonSort_clicked();

void on_pushButton_INSERT_clicked();

void on_pushButton_DELETE_clicked();

void on_pushButton_UPDATE_clicked();

void on_pushButton_SEARCH_clicked();

private:

void CreateDatabaseFunc(); // 创建SQLite数据库

void CreateTableFunc(); // 创建SQLite数据表

void QueryTableFunc(); // 执行查询操作

QSqlDatabase sqldb; // 创建Qt和数据库链接

QSqlQueryModel *model=nullptr;//用来存储数据

private:

Ui::StudentDlg *ui;

};

#endif // STUDENTDLG_H

类实现

#include "studentdlg.h"

#include "ui_studentdlg.h"

#include<QSortFilterProxyModel>

StudentDlg::StudentDlg(QWidget *parent)

: QDialog(parent)

, ui(new Ui::StudentDlg)

{

ui->setupUi(this);

// 调用函数创建且打开数据库

CreateDatabaseFunc();

// 调用函数创建数据表

CreateTableFunc();

}

StudentDlg::~StudentDlg()

{

delete ui;

}

void StudentDlg::CreateDatabaseFunc() // 创建SQLite数据库

{

// 1:添加数据库驱动

sqldb=QSqlDatabase::addDatabase("QSQLITE");

// 2:设置数据库名称

sqldb.setDatabaseName("studentmis.db");

// 3:打开此数据库是否成功

if(sqldb.open()==true)

{

QMessageBox::information(0,"正确","恭喜你,数据库打开成功!",QMessageBox::Ok);

}

else

{

QMessageBox::critical(0,"错误","数据库打开失败,请重新检测!",QMessageBox::Ok);

}

}

void StudentDlg::CreateTableFunc() // 创建SQLite数据表

{

QSqlQuery createquery;

// 创建SQL语句

QString strsql=QString("CREATE TABLE IF NOT EXISTS student("

"id int primary key not null,"

"name text not null,"

"score real not null)");

// 执行SQL语句

if(createquery.exec(strsql)==false)

{

QMessageBox::critical(0,"失败","数据表创建失败,请重新检查!",QMessageBox::Ok);

}

else

{

QMessageBox::information(0,"成功","恭喜你,数据表创建成功!",QMessageBox::Ok);

}

// 准备数据模型

model = new QSqlQueryModel();

model->setQuery("SELECT id, name, score FROM student"); // 执行查询

// 将数据模型与QTableView绑定

//QTableView *tableView = new QTableView();

ui-> tableView->setModel(model);

ui->tableView->resizeColumnsToContents(); // 调整列宽度使数据能够完全显示

// 显示QTableView

ui->tableView->show();

}

void StudentDlg::QueryTableFunc() // 执行查询操作

{

QSqlQuery query;

query.exec("SELECT * FROM users");

while(query.next()) {

int id = query.value(0).toInt();

QString name = query.value(1).toString();

double score = query.value(2).toDouble();

qDebug() << "ID:" << id << " Name:" << name << " Score:" << score;

}

}

void StudentDlg::on_pushButtonSort_clicked()

{

// QSortFilterProxyModel *sortModel = new QSortFilterProxyModel(this);

// sortModel->setSourceModel(model);

// // 设置排序的列索引

// int sortColumn = 1; // 假设要按第1列排序

// sortModel->sort(sortColumn, Qt::DescendingOrder); // 进行升序排序

// // 将排序后的模型设置给视图

// ui->tableView->setModel(sortModel);

// //使用sql语句进行操作

// QSqlQuery query;

// query.exec("SELECT id ,name ,score FROM student ORDER BY id DESC");

//更新数据库中的数据

model->setQuery("SELECT id, name, score FROM student ORDER BY id DESC");

//model->setQuery("SELECT * FROM student");

ui->tableView->viewport()->update();

}

void StudentDlg::on_pushButton_INSERT_clicked()

{

QSqlQuery sqlquery;

int id=ui->lineEdit_ID->text().toInt();

if(id==0)

{

QMessageBox::critical(this,"失败","提示:输入错误?学号不能为0?",QMessageBox::Ok);

return ;

}

QString name=ui->lineEdit_NAME->text();

if(name=="")

{

QMessageBox::critical(this,"失败","提示:输入错误?姓名不能为空?",QMessageBox::Ok);

return ;

}

double score=ui->lineEdit_SCORE->text().toDouble();

if(score<0 || score>100)

{

QMessageBox::critical(this,"失败","提示:输入错误?分数范围(0-100)?",QMessageBox::Ok);

return ;

}

QString strs=QString("insert into student "

"values(%1,'%2',%3)").arg(id).arg(name).arg(score);

if(sqlquery.exec(strs)==false)

{

QMessageBox::critical(0,"失败","向数据表插入记录失败,请重新检查!",QMessageBox::Ok);

}

else

{

QMessageBox::information(0,"成功","恭喜你,向数据表插入记录成功!",QMessageBox::Ok);

}

}

void StudentDlg::on_pushButton_DELETE_clicked()

{

int id = ui->lineEdit_ID->text().toInt();

QSqlQuery query;

query.prepare("DELETE FROM student WHERE id = :id"); // 设置删除语句

query.bindValue(":id", id); // 绑定条件值

bool success = query.exec(); // 执行删除操作

if(success) {

// 删除成功

} else {

// 删除失败,处理错误

qDebug() << "Error:" << query.lastError().text();

}

//更新数据库中的数据

model->setQuery("SELECT * FROM student");

ui->tableView->viewport()->update();

}

void StudentDlg::on_pushButton_UPDATE_clicked()

{

// 执行 UPDATE 操作

QString New_Name=ui->lineEdit_NAME->text();

int id=ui->lineEdit_ID->text().toUInt();

QSqlQuery query;

query.prepare("UPDATE student SET name = :newName WHERE id = :id");

query.bindValue(":newName", New_Name); // 设置要更新的新名称

query.bindValue(":id", id); // 设置要更新的记录的 ID

if (query.exec()) {

qDebug() << "Update successful";

} else {

qDebug() << "Update failed:" << query.lastError().text();

}

}

void StudentDlg::on_pushButton_SEARCH_clicked()

{

QSqlQuery query;

query.exec("SELECT * FROM student");

while(query.next()) {

int id = query.value(0).toInt();

QString name = query.value(1).toString();

double score = query.value(2).toDouble();

qDebug() << "ID:" << id << " Name:" << name << " Score:" << score;

}

//更新数据库中的数据

model->setQuery("SELECT * FROM student");

ui->tableView->viewport()->update();

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。