Qt对SQLite数据库的操作

目录

前言

一.准备

二.建立(打开)数据库

三.创建表格

(一)判断将要创建的表格是否存在

注意事项:QSqlQuery(查询指令)的使用!!!

(二)创建表格

(三)汇总

四.插入数据

注:因为数据都是一行为一个整体,所以建议用结构体(struct)或类(class)来储存数据,不过本文为了便于观看,并未采用结构体和类

五.查询数据

六.更新数据(修改表内容)

七.删除数据

(一)删除整表

(二)删除指定行

总结


前言

确实差不多有半年没发文了,不过在我持续的学习中,SQLite数据库的操作始终必不可少,在一次次的查找后,总结出此文

而本文因为涉及到的东西有点多,各位可以通过目录来定点打击哦

一.准备

Qt本身并没有操作SQLite的相关模块,因此需要提前在.pro文件中引入如下代码:

cpp 复制代码
QT       += core gui sql

然后,引入操作需要的一系列配套头文件:

cpp 复制代码
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>

这里的QDebug是为了后面的调试报错,最好还是加上

二.建立(打开)数据库

准备工作完毕,接下来如果还没有数据库,那么就建立一个;那如果有呢?只用打开就行了

而有无数据库的判断并不需要我们费心,Qt会自行判断:

cpp 复制代码
//创建一个数据库
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("LeafDB.db");//这里的数据库名随便改哦
//打开数据库
if(!db.open())qDebug() << "Fail to open database:" <<db.lastError();
else qDebug()<<"Succeed in openning database.";

三.创建表格

(一)判断将要创建的表格是否存在

由于我们是在程序中创建表格,那么在每次程序启动时,一个表格都会被创建一次,虽然说如果想要创建的表格已经存在,数据库并不会再创建一个表格,但是这样会消耗部分时间,而且创建表失败所报的提示也有可能使我们晕头转向,因此,在创建表格前先判断是很有必要的

而要判断也很简单,只需要用一次查询语句:

cpp 复制代码
bool isTableExist = query.exec("select * from myTable");//这里的myTable是后面将要创建的表的名字
if(isTableExist != true){//此表不存在
    //建表
}else qDebug()<<"The table you wanna create has already existed.";

注意事项:QSqlQuery(查询指令)的使用!!!

在很多博客中,你可能会看到像下面这样定义query的

cpp 复制代码
QSqlQuery query;

但是部分人会遇到这种情况:

很多人会心生疑惑,前面不是把数据库打开了吗,为什么这里显示数据库未被打开??

实际这是Qt系统为我们提供的一个便利,如果我们仅仅只有一个连接,那么系统默认将QSqlQuery关联到了默认的唯一的数据库连接上了。所以,QSqlQuery::exec: database not open这样的问题就会烦倒很多新手

那么,为了避免这种情况的产生,我们只需要小小的做一个改动

法一:

cpp 复制代码
QSqlQuery query = QSqlQuery(db);

法二:

cpp 复制代码
QSqlQuery query(db);

这里我们直接强制性的将query联系到了前面创建的数据库db中,那么上述问题便能得到解决,我们接着往下走

(二)创建表格

示例代码如下:

cpp 复制代码
QString sqlCreateTable = QString("create table myTable(id integer primary key autoincrement,"
                                          "name varchar(4),"
                                          "age int,"
                                          "address varchar(20))");
if(!query.exec(sqlCreateTable))qDebug() << "Fail to create a table:" <<db.lastError();
else qDebug()<<"Succeed in creating a table.";

关于代码中的数据类型问题,可以参考如下表格:

而示例代码中的"id integer primary key autoincrement"则意为id自增

(三)汇总

那么综上所述,整个建表的代码如下:

cpp 复制代码
QSqlQuery query = QSqlQuery(db);
bool isTableExist = query.exec("select * from myTable");//这里的myTable是后面将要创建的表的名字
if(isTableExist != true){//此表不存在
    QString sqlCreateTable = QString("create table myTable(id integer primary key autoincrement,"
                                               "name varchar(4),"
                                               "age int,"
                                               "address varchar(20));");
    if(!query.exec(sqlCreateTable))qDebug() << "Fail to create a table:" <<db.lastError();
    else qDebug()<<"Succeed in creating a table.";
}else qDebug()<<"The table you wanna create has already existed.";

四.插入数据

注:因为数据都是一行为一个整体,所以建议用结构体(struct)或类(class)来储存数据,不过本文为了便于观看,并未采用结构体和类

在建完表后的下一步便是向这个表里面塞东西了

众所周知,向数据库中插入数据的查询语句如下:

sql 复制代码
INSERT INTO TABLE_NAME VALUES (value1, value2, value3,...valueN);

由此可见,我们需要向这一整个查询语句中加入value这一变量

难道------

cpp 复制代码
QString addDatas = "insert into myTable values(";
addDatas += "张三,";
addDatas += "21,";
addDatas += "人民公园";
addDatas += ");";
query.exec(addDatas);

吗?

这显然是不现实的,那么这个时候,我们就可以用到QSqlQuery中的prepare()函数了

那么刚才上面的那么一大坨,可以变成:

cpp 复制代码
query.prepare("insert into myTable values(?,?,?);");//用?来给后面的数据占位置
query.bindValue(0, name);//逐个添加,0为索引
query.bindValue(1, QString(age));//注意,这里的变量都要转化为QString类型
query.bindValue(2, address);
query.exec();

(从6行变到5行也是一个进步......)

但是我们的重点并不在这,对比以上的两种方法,我们会很明显的发现,第一种的可读性太差,时间久了或者项目做大了再来看很容易让大脑宕机

因此,加上调试内容后,以下便是最终的代码:

cpp 复制代码
query.prepare("insert into myTable values(?,?,?);");//用?来给后面的数据占位置
query.bindValue(0, name);//逐个添加,0为索引
query.bindValue(1, QString(age));//注意,这里的变量都要转化为QString类型
query.bindValue(2, address);

bool isAddSucceed = query.exec();
if(!isAddSucceed)qDebug() << "Fail to insert:" << query.lastError().text();
else qDebug()<<"Succeed in inserting.";

五.查询数据

查询的总体思路就是通过query去数据库中读表,然后通过query.next()逐步拆解读到的表的数据即可,这里就不再过多赘述

cpp 复制代码
QString sqlselect = QString("select * from myTable;");
if(!query.exec(sqlselect))qDebug()<<"insert data error" <<db.lastError();
else{//读表成功
    while (query.next()){//切换到表格的下一行
        //逐个获取该行表头中的数据
        qDebug()<<query.value("name").toString();
        qDebug()<<query.value("age").toInt();
        qDebug()<<query.value("address").toString();
    }
}

六.更新数据(修改表内容)

在SQLite的查询指令中,更新是这样的:

sql 复制代码
UPDATE table_name
SET column1=value1, column2=value2...., columnN=valueN
WHERE [condition];

那么仍然使用我们的prepare()函数去更新(这里where后的条件一般都使用的是id)

cpp 复制代码
query.prepare("update myTable set name = ? where ID = ?");
//这里的newName和id要相对应,即处于同一行
query.bindValue(0, newName);//新的数据,用于替换原有数据
query.bindValue(1, id);

bool isUpdate = query.exec();
if(!isUpdate)qDebug() << "Fail to update myTable set name:"<<query.lastError().text();
else qDebug()<<"Succeed in updating.";

七.删除数据

由于删除的操作比较简单,调试部分就不给大家贴了

(一)删除整表

那这个就非常简单了,如下

cpp 复制代码
query.exec("DELETE FROM myTable");//删除myTable表里所有内容

(二)删除指定行

cpp 复制代码
query.prepare("DELETE FROM myTable WHERE  id = ?");
query.bindValue(0, id);//想要删除行的id

总结

以上便是我能想到的所有SQLite的Qt操作了,如果还有其他的需要,欢迎在评论区告诉我,我在看到后会第一时间加入,希望本文能对各位有所帮助

相关推荐
中二病码农不会遇见C++学姐2 小时前
《文明6》Mod开发实战:从游戏日志定位和解决Mod加载问题
数据库·游戏·oracle
小小码农Come on2 小时前
QT布局介绍
开发语言·qt
云中飞鸿2 小时前
QTCreator error: C3861: “_mm_loadu_si64”: 找不到标识符
qt
naruto_lnq2 小时前
Python日志记录(Logging)最佳实践
jvm·数据库·python
酉鬼女又兒2 小时前
SQL23 统计每个学校各难度的用户平均刷题数
数据库·sql·算法
bigdata-rookie2 小时前
Starrocks 简介
大数据·数据库·数据仓库
2301_765703142 小时前
Python异步编程入门:Asyncio库的使用
jvm·数据库·python
PacosonSWJTU2 小时前
大模型应用开发rag-第1个rag应用
数据库·语言模型
CodeByV2 小时前
【Qt】信号与槽
开发语言·qt