目录
注:因为数据都是一行为一个整体,所以建议用结构体(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操作了,如果还有其他的需要,欢迎在评论区告诉我,我在看到后会第一时间加入,希望本文能对各位有所帮助