Qt从入门到入土(十) -数据库操作--SQLITE

认识

数据库是用于存储、管理和检索数据的系统化集合。它是一种按照特定结构组织数据的存储方式,通过软件(数据库管理系统,DBMS)来实现数据的高效存储、查询、更新和管理。通过文件存储数据适用于少量的数据,而当拥有几十万上百万条数据时,通过文件读写数据所耗的时间就非常长,因此当数据量很大时,就需要使用数据库来存储数据。本文主要介绍了SQLITE的用法。

导入数据库模块

在CMakeLists.txt文件中加入Sql模块

 

 如果使用qmake编译,则在.pro文件中加入以下代码

QT += core gui sql

 引用头文件QSqlDatabase查看模块是否导入成功

#include "mainwindow.h"#include <QApplication>
#include <QSqlDatabase>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;qDebug()<<QSqlDatabase::drivers();   // 查看支持的驱动w.show();return a.exec();
}

打开数据库

void openDatabase()
{qDebug()<<QSqlDatabase::drivers();   // 查看支持的驱动// 添加数据库auto database = QSqlDatabase::addDatabase("QSQLITE");// 设置数据库名称database.setDatabaseName("student.db");// 打开数据库if(!database.open()){qDebug()<<database.databaseName()<<"open failed:"<< database.lastError();return;}qDebug()<<"打开数据库成功!";
}

打开数据库成功后会创建一个student.db的文件用于存放数据信息

创建表

// 创建表QSqlQuery query(database);   // 连接到database数据库上auto res = query.exec(R"(CREATE TABLE IF NOT EXISTS students (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER))");// 判断表是否创建成功if(!res){qDebug()<<query.lastError().text();return;}qDebug()<<"表创建成功!";

 SQL语句解读:

1. CREATE TABLE IF NOT EXISTS users

  • CREATE TABLE:这是 SQL 语句的开头,表示要创建一个新的表。

  • IF NOT EXISTS:这是一个可选的条件,用于检查表是否已经存在。如果表已经存在,则不会重复创建,避免了因重复创建表而导致的错误。

  • students:这是新表的名称,表示要创建一个名为 students 的表。

2. id INTEGER PRIMARY KEY AUTOINCREMENT

  • id:这是表中的一个字段名称,表示每个用户的唯一标识符。

  • INTEGER:这是字段的数据类型,表示 id 字段存储整数类型的数据。

  • PRIMARY KEY:这是一个约束,表示 id 字段是表的主键。主键用于唯一标识表中的每一行记录,不能有重复值。

  • AUTOINCREMENT:这是一个特殊的约束,表示 id 字段的值会自动递增。每次插入新记录时,如果未指定 id 的值,SQLite 会自动为该字段生成一个唯一的整数值。

3. name TEXT NOT NULL

  • name:这是表中的另一个字段名称,表示用户的姓名。

  • TEXT:这是字段的数据类型,表示 name 字段存储文本类型的数据。

  • NOT NULL:这是一个约束,表示 name 字段不能为空。在插入或更新数据时,必须为该字段提供一个值,否则会报错。

4. age INTEGER

  • age:这是表中的另一个字段名称,表示用户的年龄。

  • INTEGER:这是字段的数据类型,表示 age 字段存储整数类型的数据。

  • 没有约束:这里没有为 age 字段指定 NOT NULL 约束,因此 age 字段可以为空(即允许插入 NULL 值)。

查看字段

    // 查看当前数据库有哪些表qDebug()<<database.tables();// 查看表中字段QSqlRecord record = database.record("students");qDebug()<<"有"<<record.count()<<"个字段";for(size_t i = 0;i<record.count();++i){qDebug()<<record.fieldName(i);}

插入数据

    // 只能作为初始化插入一次,否则会报错auto sql = R"(INSERT INTO students(id,name,age) VALUES (1,'张三',18),(2,'李四',20),(3,'王五',50);)";if(!query.exec(sql)){qDebug()<<"插入数据失败:"<<query.lastError();return;}
    // 插入固定数据(单条)int id = 5;QString name = "超人强";int age = 18;// 准备语句,使用?作为占位符if(!query.prepare(R"(INSERT INTO students(id,name,age) VALUES(?,?,?))")){qDebug()<<"插入数据失败"<<query.lastError();return;}else{// 使用bindValue来绑定// query.bindValue(0,id);// query.bindValue(1,name);// query.bindValue(2,age);// 默认从0开始绑定query.addBindValue(id);query.addBindValue(name);query.addBindValue(age);if(!query.exec()){qDebug()<<"error"<<query.lastError();}}
    // 插入多条数据QVariantList id_list{7,8,9};QVariantList name_list{"猪猪侠","小猪猪","ggbond"};QVariantList age_list{18,18,18};if(!query.prepare(R"(INSERT INTO students(id,name,age) VALUES(?,?,?))")){qDebug()<<"插入数据失败"<<query.lastError();return;}query.addBindValue(id_list);query.addBindValue(name_list);query.addBindValue(age_list);// 批量插入if(!query.execBatch()){qDebug()<<"批量插入失败"<<query.lastError();return;}

删除数据

    // 删除数据if(!query.exec(R"(DELETE FROM students WHERE id = 1)")){qDebug()<<"数据删除失败!"<<query.lastError();return;}

修改数据

    // 修改数据if(!query.exec(R"(UPDATE students SET name = '王八蛋' WHERE name = '李四')")){qDebug()<<"更新数据失败!"<<query.lastError();return;}

查询数据

    // 查询数据if(!query.exec("SELECT * FROM students")){qDebug()<<"查询数据失败"<<query.lastError();return;}

打印数据

    // 打印全部数据while(query.next()){QSqlRecord record = query.record();qDebug()<<record.value("id")<<record.value("name")<<record.value("age");}

 测试代码

void test_database()
{qDebug()<<QSqlDatabase::drivers();   // 查看支持的驱动// 添加数据库auto database = QSqlDatabase::addDatabase("QSQLITE","connect");// 设置数据库名称database.setDatabaseName("student.db");// 打开数据库if(!database.open()){qDebug()<<database.databaseName()<<"open failed:"<< database.lastError();return;}qDebug()<<"打开数据库成功!";// 创建表QSqlQuery query(database);   // 连接到database数据库上auto res = query.exec(R"(CREATE TABLE IF NOT EXISTS students (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER))");// 判断表是否创建成功if(!res){qDebug()<<query.lastError().text();return;}qDebug()<<"表创建成功!";// 查看当前数据库有哪些表qDebug()<<database.tables();// 查看表中字段QSqlRecord record = database.record("students");qDebug()<<"有"<<record.count()<<"个字段";for(size_t i = 0;i<record.count();++i){qDebug()<<record.fieldName(i);}// 插入数据// 只能作为初始化插入一次,否则会报错// auto sql = R"(INSERT INTO students(id,name,age) VALUES (1,'张三',18),(2,'李四',20),(3,'王五',50);)";// if(!query.exec(sql))// {//     qDebug()<<"插入数据失败:"<<query.lastError();//     return;// }// 插入固定数据(单条)int id = 5;QString name = "超人强";int age = 18;// 准备语句,使用?作为占位符if(!query.prepare(R"(INSERT INTO students(id,name,age) VALUES(?,?,?))")){qDebug()<<"插入数据失败"<<query.lastError();return;}else{// 使用bindValue来绑定// query.bindValue(0,id);// query.bindValue(1,name);// query.bindValue(2,age);// 默认从0开始绑定query.addBindValue(id);query.addBindValue(name);query.addBindValue(age);if(!query.exec()){qDebug()<<"error"<<query.lastError();}}// 插入多条数据QVariantList id_list{7,8,9};QVariantList name_list{"猪猪侠","小猪猪","ggbond"};QVariantList age_list{18,18,18};if(!query.prepare(R"(INSERT INTO students(id,name,age) VALUES(?,?,?))")){qDebug()<<"插入数据失败"<<query.lastError();return;}query.addBindValue(id_list);query.addBindValue(name_list);query.addBindValue(age_list);// 批量插入if(!query.execBatch()){qDebug()<<"批量插入失败"<<query.lastError();return;}// 删除数据if(!query.exec(R"(DELETE FROM students WHERE id = 1)")){qDebug()<<"数据删除失败!"<<query.lastError();return;}// 修改数据if(!query.exec(R"(UPDATE students SET name = '王八蛋' WHERE name = '李四')")){qDebug()<<"更新数据失败!"<<query.lastError();return;}// 查询数据if(!query.exec("SELECT * FROM students")){qDebug()<<"查询数据失败"<<query.lastError();return;}// 打印全部数据while(query.next()){QSqlRecord record = query.record();qDebug()<<record.value("id")<<record.value("name")<<record.value("age");}// 关闭数据库database.close();
}

接口封装

#include <QApplication>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>// 初始化数据库(创建表)
void initDatabase(QSqlQuery& q)
{auto sql = R"(CREATE TABLE IF NOT EXISTS manager(id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,age INTEGER))";if(!q.exec(sql)){qDebug()<<"创建表失败!"<<q.lastError();return;}qDebug()<<"创建表成功!";
}// 增加数据
void insertData(QVariant id,QVariant name,QVariant age,QSqlQuery& q)
{// 准备语句,使用?作为占位符if(!q.prepare(R"(INSERT INTO manager(id,name,age) VALUES(?,?,?))")){qDebug()<<"插入数据失败"<<q.lastError();return;}else{// 插入单条数据q.addBindValue(id);q.addBindValue(name);q.addBindValue(age);if(!q.exec()){qDebug()<<"error"<<q.lastError();return;}qDebug()<<"插入数据成功!";}
}// 删除数据
void deleteData(QVariant id,QSqlQuery& q)
{// 准备删除语句if (!q.prepare("DELETE FROM manager WHERE id = :id")){qDebug() << "准备删除语句失败:" << q.lastError();return;}// 绑定参数q.bindValue(":id", id.toInt());// 执行删除操作if (!q.exec()){qDebug() << "数据删除失败!" << q.lastError();return;}qDebug() << "删除数据成功!";
}
// 修改数据
void modifyData(QSqlQuery& q,QVariant name,QVariant newName)
{// 修改数据if(!q.prepare("UPDATE manager SET name = :newName WHERE name = :name")){qDebug()<<"准备更新数据失败!"<<q.lastError();return;}q.bindValue(":newName",newName.toString());q.bindValue(":name",name.toString());if(!q.exec()){qDebug()<<"更新数据失败!"<<q.lastError();return;}qDebug()<<"修改数据成功!";}
// 查询数据
void searchData(QSqlQuery& q,QVariant name)
{// 查询数据if(!q.exec("SELECT * FROM manager")){qDebug()<<"查询数据失败"<<q.lastError();return;}while(q.next()){QSqlRecord rec = q.record();if(name == rec.value("name")){qDebug()<<"查询数据成功:"<<rec.value("id")<<rec.value("name")<<rec.value("age");}}
}
// 打印所有数据
void printData(QSqlQuery& q)
{// 执行查询语句if (!q.exec("SELECT * FROM manager")) {qDebug() << "查询失败:" << q.lastError();return;}while(q.next()){QSqlRecord rec = q.record();qDebug()<<rec.value("id")<<rec.value("name")<<rec.value("age");}
}int main(int argc, char *argv[])
{QApplication a(argc, argv);auto db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("manager.db");if(!db.open()){qDebug()<<"数据库打开失败"<<db.lastError();return -1;}qDebug()<<"数据库创建成功!";QSqlQuery query(db);initDatabase(query);insertData(1,"张三",18,query);printData(query);deleteData(1,query);printData(query);modifyData(query,"张三","张无忌");printData(query);searchData(query,"张三");return a.exec();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/33431.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式2-按键

一、按键 1.原理图&#xff1a; P14按下低电平&#xff0c;不按则高电平。 if((t&(1<<5))!0)& 优先级 8 ! 优先级 7 二、STC89Cxx中文参考手册 1.ram(随机访问存储器&#xff09;易失性 1.1sram&#xff08;512字节&#xff09;静态存储器 2.rom(只读存储…

论文分享 | HE-Nav: 一种适用于复杂环境中空地机器人的高性能高效导航系统

阿木实验室始终致力于通过开源项目和智能无人机产品&#xff0c;为全球无人机开发者提供强有力的技术支持&#xff0c;并推出了开源项目校园赞助活动&#xff0c;助力高校学子在学术研究与技术创新中取得更大突破。近日&#xff0c;香港大学王俊铭同学&#xff0c;基于阿木实验…

平安养老险广西分公司2025年“3∙15”金融消费者权益教育宣传活动暨南湖公园健步行活动

2025年3月11日&#xff0c;由国家金融监督管理总局广西监管局、中国人民银行广西壮族自治区分行指导&#xff0c;平安养老保险股份有限公司&#xff08;以下简称“平安养老险”&#xff09;广西分公司联合平安银行南宁分行、平安人寿广西分公司、平安产险广西分公司、平安证券广…

学习threejs,使用MeshFaceMaterial面材质容器

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.MeshFaceMaterial 二…

电脑内存不足怎么办?

常规解决方法盘点 关闭后台程序&#xff1a;按下【Ctrl Shift Esc】组合键打开任务管理器&#xff0c;在 “进程” 选项卡里&#xff0c;把当前不用的程序统统 “结束任务” &#xff0c;像那些自动更新的软件、常驻后台的播放器&#xff0c;关了能释放不少内存。比如音乐软…

Excel中国式排名,3种方法!

大家好&#xff0c;我是小鱼。 什么是中国式排名呢&#xff1f; 举个例子比如说公司一共有10名员工进行成绩考核&#xff0c;如果9个人考核成绩都是90分&#xff0c;你是89分&#xff0c;按照国际惯用的排名法则&#xff1a;9 个人考核成绩并列第一&#xff0c;你第10名&…

deepseek+kimi做ppt教程记录

1.首先注册deepseek和kimi deepseek官网&#xff1a;https://chat.deepseek.com/ kimi官网&#xff1a;https://kimi.moonshot.cn/ 以下以一篇工作总结报告为例 2.使用deepseek生成ppt大纲 让deepseek生成kimi生成ppt所需要的内容时&#xff0c;需要注意提示词内容&#xff0c;…

前端无限滚动内容自动回收技术详解:原理、实现与优化

文章目录 一、核心需求与技术挑战1.1 无限滚动的问题症结1.2 自动回收的三大目标 二、技术实现原理2.1 虚拟滚动核心机制2.2 关键技术指标 三、完整实现方案3.1 基础HTML结构3.2 CSS关键样式3.3 JavaScript核心逻辑3.3.1 滚动控制器3.3.2 动态尺寸处理 四、性能优化策略4.1 内存…

【训练细节解读】文本智能混合分块(Mixtures of Text Chunking,MoC)引领RAG进入多粒度感知智能分块阶段

RAG系统在处理复杂上下文时,传统和语义分块方法的局限性,文本分块的质量限制了检索到的内容,从而影响生成答案的准确性。尽管其他算法组件有所进步,但分块策略中的增量缺陷仍可能在一定程度上降低整体系统性能。如何直接量化分块质量?如何有效利用大型语言模型(LLMs)进行…

Jmeter下载及环境配置

Jmeter下载及环境配置 java环境变量配置配置jdk环境变量检查是否配置成功JMeter下载 java环境变量配置 访问地址&#xff1a; https://www.oracle.com/cn/java/technologies/downloads/ 注意&#xff1a;需要自己注册账号 下载完成&#xff0c;解压后的目录为&#xff1a; …

coze ai assistant Task 2

创建一个智能体&#xff1a;夸夸机器人 https://www.coze.cn/store/agent/7480939060010713138?bot_idtrue 改为豆包系列-豆包角色扮演 添加bingWebSearch搜索 添加前&#xff1a; 添加后&#xff1a; 改为工具调用&#xff1a; 添加知识库 使用长期记忆 结合自己的需求&…

Unity基于C#+UGUI解决方案,制作每日签到系统(本地存储签到数据)

一、需求介绍:基于本地存储系统制作一个每日签到系统界面,相关签到界面如下图所示,点击“签到有礼”按钮后就会跳转到“每日登录礼”这个界面,点击“立即签到”按钮之后,按钮就会置灰,而且按钮的文字会变成“等待明日”。 二、制作界面显示相关功能,需要在Unity中新建一…

多线程(超详细) (ε≡٩(๑>₃<)۶ 一心向学)

多线程目录 一、认识线程 1、概念&#xff1a; 1) 线程是什么 2) 线程为什么存在 3) 进程与线程的区别 二、创建线程 1、方法1&#xff1a;继承Thread类 2、方法2&#xff1a;实现 Runnable 接口 3、方法3&#xff1a;匿名内部类创建 Thread 子类对象 4、方法4&#…

SpringBoot——Maven篇

Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的工具。它具有许多特性&#xff0c;其中一些重要的特性包括&#xff1a; 1. 自动配置&#xff1a;Spring Boot 提供了自动配置的机制&#xff0c;可以根据应用程序的依赖和环境自动配置应用程序的各种组件&#xff…

中文大语言模型提示工程:解锁AI力量的密钥(完整优化版)

文章目录 **引言&#xff1a;AI时代的"咒语"革命****一、为什么中文提示工程是技术深水区&#xff1f;****1.1 中文的"模糊美学"挑战****1.2 文化认知鸿沟****1.3 分词歧义陷阱** **二、中文提示工程六脉神剑&#xff08;附实战代码&#xff09;****2.1 结…

C++中虚析构函数的作用是什么?为什么基类需要虚析构函数?

C中虚析构函数的作用是什么&#xff1f;为什么基类需要虚析构函数&#xff1f; 在C中&#xff0c;虚析构函数&#xff08;virtual destructor&#xff09;的作用是确保在通过基类指针或引用删除派生类对象时&#xff0c;能够正确调用派生类的析构函数&#xff0c;从而避免资源…

【C++项目实战】校园公告搜索引擎:完整实现与优化指南

&#x1f3ac; 个人主页&#xff1a;谁在夜里看海. &#x1f4d6; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长&#xff0c;行则将至 目录 &#x1f4da;一、项目概述 &#x1f4d6;1.项目背景 &#x1f4d6;2.主要功能 &#x1f4d6;3.界面展…

大数据技术之Spark优化

第 1 章 Spark 性能调优 问:spark 优化 第一句:我们可以从性能,算子,shuffle 过程以及 jvm 四个方面展开优化。 1 常规性能调优 1.1 常规性能调优一:最优资源配置 Spark 性能调优的第一步,就是为任务分配更多的资源,在一定范围内,增加资源的分配与性能的提升是成正…

【 Manus平替开源项目】

文章目录 Manus平替开源项目1 OpenManus1.1 简介1.2 安装教程1.3 运行 2 OWL2.1 简介2.2 安装教程2.3 运行 3 OpenHands&#xff08;原OpenDevin&#xff09;3.1 简介3.2 安装教程和运行 Manus平替开源项目 1 OpenManus 1.1 简介 开发团队: MetaGPT 核心贡献者&#xff08;5…

《Java SQL 操作指南:深入理解 Statement 用法与优化》

在 Java 数据库编程中&#xff0c;Statement 是用于执行 SQL 语句的接口&#xff0c;允许程序与数据库进行交互。本文将详细介绍 Statement 的基本概念、常见用法以及 PreparedStatement 和 CallableStatement 等相关接口。 1. Statement 基本介绍 Statement 接口继承了 AutoC…