嵌入式 SQLite 数据库开发笔记

嵌入式 SQLite 数据库开发入门笔记

在嵌入式开发中,数据存储与管理是不可或缺的环节。对于资源有限的系统,轻量级数据库 SQLite 是一个非常理想的选择。它无需独立服务进程,直接嵌入到应用中即可使用,既能满足数据持久化需求,又不会过多占用系统资源。本文将结合实践代码,系统梳理 SQLite 在嵌入式中的使用方法。


一、SQLite 简介

  • 定义
    SQLite 是一个轻量级的关系型数据库管理系统(RDBMS),以文件形式存储数据,零配置、跨平台、易移植。

  • 适用场景

    • 嵌入式设备(路由器、物联网设备、手持终端)

    • 本地应用配置存储

    • 移动端(Android、iOS 应用)

  • 数据组织结构

数据库(Database) -> 表(Table) -> 行(Row) -> 列(Column)

二、SQLite 命令行工具常用操作

SQLite 提供了简单的命令行工具,非常适合调试和学习。

命令功能说明
.help显示帮助信息
.database显示当前打开的数据库文件
.tables列出数据库中所有表
.schema 表名查看表结构
.header on打开表头显示
.quit / .q退出 SQLite 命令行工具
  • 常用 SQL 语法

-- 插入数据
INSERT INTO user VALUES (1, 'zhangsan', 25);-- 查询数据
SELECT * FROM user;
SELECT name, age FROM user WHERE age > 20;-- 更新数据
UPDATE user SET age=26 WHERE id=1;-- 删除数据
DELETE FROM user WHERE id=2;

三、C 语言调用 SQLite

在嵌入式开发中,我们通常通过 SQLite 提供的 C API 来操作数据库。

1. 基本流程

sqlite3 *db = NULL;
int ret = sqlite3_open("./aaa.db", &db);
if (ret != SQLITE_OK) {fprintf(stderr, "sqlite3_open error: %s\n", sqlite3_errstr(ret));sqlite3_close(db);return 1;
}char sql_cmd[] = "INSERT INTO user VALUES(11,'lisi',20);";
char *errmsg = NULL;
ret = sqlite3_exec(db, sql_cmd, NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {fprintf(stderr, "sqlite3_exec error: %s\n", errmsg);sqlite3_free(errmsg);sqlite3_close(db);return 1;
}sqlite3_close(db);
  • sqlite3_open():打开数据库文件,不存在则新建。

  • sqlite3_exec():执行 SQL 语句。

  • sqlite3_close():关闭数据库。


四、回调函数处理查询结果

执行 SELECT 查询时,sqlite3_exec() 可以传入一个 回调函数,用来逐行处理结果。

1. 回调函数原型

int callback(void *arg, int col, char **result, char **title);
  • arg:用户自定义数据指针(sqlite3_exec 的第四个参数传入)。

  • col:当前行的列数。

  • result:字符串数组,存放每列的值。

  • title:字符串数组,存放每列的列名。

👉 特性:

  • 如果有多条结果,回调函数会被多次调用。

  • 如果结果为空,回调函数不会被调用。

2. 示例代码

#include <sqlite3.h>
#include <stdio.h>int show(void* arg, int col, char** result, char** title)
{static int flag = 0; // 表头只打印一次int i = 0;if (flag == 0) {flag = 1;for (i = 0; i < col; i++) {printf("%s\t", title[i]);}printf("\n");}for (i = 0; i < col; i++) {printf("%s\t", result[i] ? result[i] : "NULL");}printf("\n");return 0;
}int main()
{sqlite3* db = NULL;char* errmsg = NULL;int ret = sqlite3_open("./aaa.db", &db);if (ret != SQLITE_OK) {fprintf(stderr, "sqlite3_open %s\n", sqlite3_errstr(ret));sqlite3_close(db);return 1;}char sql_cmd[] = "SELECT * FROM user;";ret = sqlite3_exec(db, sql_cmd, show, NULL, &errmsg);if (ret != SQLITE_OK) {fprintf(stderr, "sqlite3_exec error: %s\n", errmsg);sqlite3_free(errmsg);sqlite3_close(db);return 1;}sqlite3_close(db);return 0;
}

3. 输出示例

假设表内容如下:

CREATE TABLE user (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);
INSERT INTO user VALUES (1, 'zhangsan', 25);
INSERT INTO user VALUES (2, 'lisi', 30);

程序运行结果:

id    name    age
1     zhangsan    25
2     lisi        30

五、嵌入式 SQLite 开发心得

  1. 数据库文件位置

    • 嵌入式系统 Flash 容量有限,建议放在合适的分区,并避免频繁写入。

  2. 事务优化

    • 默认每次写入都会同步到磁盘,效率低。

    • 使用事务:

      BEGIN TRANSACTION;
      INSERT INTO user VALUES(3,'wangwu',22);
      INSERT INTO user VALUES(4,'zhaoliu',28);
      COMMIT;
      

      可以显著提高批量插入速度。

  3. 内存占用

    • SQLite 默认内存消耗较低,但在嵌入式系统中仍需注意查询规模,避免一次性查询过大数据集。

  4. 回调 vs 预编译接口

    • sqlite3_exec() 简单易用,适合小型查询。

    • 更复杂场景可使用 预编译语句 APIsqlite3_prepare_v2 / sqlite3_step / sqlite3_finalize),性能更好。


六、总结

SQLite 在嵌入式系统中有以下优势:

  • 单文件存储,移植方便

  • 零配置、无需后台进程

  • 支持标准 SQL,功能完备

  • 资源占用低,适合嵌入式场景

通过本文的学习,你可以在嵌入式系统中完成数据库文件的创建、数据的增删改查,以及通过 回调函数 高效获取查询结果。

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

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

相关文章

Spark面试题及详细答案100道(71-80)-- 配置与部署

《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

Redis 面试

1、主从集群1、构建主从集群单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离。主写从读&#xff0c;主可以读也可以写&#xff0c;从只能读利用docker-compose文件来构建主从集群&#xff1a;…

如何使用PostgreSQL数据库进行数据挖掘与预测分析

如何使用PostgreSQL数据库进行数据挖掘与预测分析 关键词:PostgreSQL,数据挖掘,预测分析,数据库,机器学习 摘要:本文旨在深入探讨如何利用PostgreSQL数据库进行数据挖掘与预测分析。首先介绍了使用PostgreSQL进行此类操作的背景信息,包括目的、预期读者、文档结构等。接…

ZooKeeper vs Redis:分布式锁的实现与选型指南

一、Redis 分布式锁&#xff1a;追求极致的性能 Redis 分布式锁基于内存操作&#xff0c;其核心思想是在内存中设置一个唯一的键值对来表示锁的持有。 1. 基础实现&#xff08;SETNX Lua&#xff09; 最简单的实现是使用 SETNX&#xff08;SET if Not eXists&#xff09;命令&…

vue基于Springboot框架的考研咨询平台系统实现

目录前言-本系统介绍已开发项目效果实现截图开发技术详细介绍核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码获取详细视频演示或者查看其他版本&#xff1a;文章底部获取博主联系方式&…

苹果用户速更新!macOS存严重漏洞,用户隐私数据面临泄露风险

漏洞概况近日&#xff0c;macOS系统发现一个CVSS评分高达 9.8 的高危漏洞&#xff0c;该漏洞可能允许应用程序绕过系统保护机制&#xff0c;非法访问受保护的用户数据。该漏洞编号为 CVE-2025-24204&#xff0c;目前已有概念验证&#xff08;PoC&#xff09;代码公开。漏洞影响…

海盗王64位dx9客户端修改篇之五

在海盗王3.0客户都升级64位dx9版本的过程中&#xff0c;因为特效的问题&#xff0c;被卡壳了很久。 开始是精灵草的粒子效果、白银城的烟囱烟雾效果、篝火的效果、阳光透射效果、海浪效果等&#xff0c;修了很长的时间&#xff0c;才找到窍门弄好。 然后是精灵效果、角色阴影。…

Linux学习——管理网络安全(二十一)

一、管理服务器防火墙&#xff08;firewalld&#xff09;RHEL 默认使用 firewalld 作为防火墙管理工具&#xff0c;它通过 “区域&#xff08;zone&#xff09;” 和 “服务&#xff08;service&#xff09;” 的概念简化规则配置&#xff0c;支持动态更新规则而无需重启服务。…

leetcode-python-1941检查是否所有字符出现次数相同

题目&#xff1a; 给你一个字符串 s &#xff0c;如果 s 是一个 好 字符串&#xff0c;请你返回 true &#xff0c;否则请返回 false 。 如果 s 中出现过的 所有 字符的出现次数 相同 &#xff0c;那么我们称字符串 s 是 好 字符串。 示例 1&#xff1a; 输入&#xff1a;s “…

Snort的介绍

当然可以。以下是对 Snort 的全面介绍&#xff0c;涵盖其定义、核心功能、三种运行模式、工作原理、规则系统以及应用场景等内容。 Snort 网络入侵检测系统&#xff08;NIDS&#xff09;详解 一、Snort 简介 Snort 是一款开源的、轻量级但功能强大的 网络入侵检测与防御系统&…

滴滴二面准备(一)

结合你的简历内容和技术面试问题&#xff0c;以下是一个结构化的回答建议&#xff0c;突出你的技术深度和项目经验&#xff1a;2. 项目与实习经历 得物低代码落地页编辑器&#xff08;核心项目&#xff09; 背景&#xff1a;解决软广落地页开发周期长、迭代慢问题。技术方案&am…

socket通信在Windows和Linux上的区别

前言 笔者在将socket通信的自定义类从Linux移植到Windows时遇到一些问题&#xff0c;整理下来希望帮助到需要的人&#xff0c;同时也加深自己的理解。 差异 头文件 #ifdef _WIN32 #include <ws2tcpip.h> #define inet_pton InetPton #define SHUT_RDWR SD_BOTH #define M…

一款将PDF转化为机器可读格式的工具介绍

ps:以下内容来自MinerU项目 MinerU 项目简介 MinerU是一款将PDF转化为机器可读格式的工具&#xff08;如markdown、json&#xff09;&#xff0c;可以很方便地抽取为任意格式。 MinerU诞生于书生-浦语的预训练过程中&#xff0c;我们将会集中精力解决科技文献中的符号转化问…

代码随想录算法训练营第三十九天|62.不同路径 63.不同路径ll

62.不同路径&#xff1a; 文档讲解&#xff1a;代码随想录|62.不同路径 视频讲解&#xff1a;https://www.bilibili.com/video/BV1ve4y1x7Eu 状态&#xff1a;已做出 一、题目要求&#xff1a; 一个二维数组里&#xff0c;将(0&#xff0c;0)位置下标作为起点&#xff0c;计算…

openEuler2403安装部署Prometheus和Grafana

文章目录openEuler2403安装部署Prometheus和Grafana一、前言1.简介2.环境二、正文1.环境准备1&#xff09;JDK 安装部署&#xff08;可选&#xff09;2&#xff09;关闭防火墙2.安装 Prometheus1&#xff09;下载和安装2&#xff09;启动3&#xff09;systemd服务管理3.安装 Gr…

乐吾乐大屏可视化组态软件【SQL数据源】

乐吾乐大屏可视化组态软件&#xff08;大屏可视化设计器 - 乐吾乐Le5le&#xff09;支持直接对接SQL数据源功能&#xff0c;目前仅对企业源码客户开放。 配置SQL数据源 管理员进入可视化管理中心&#xff0c;点击SQL数据源&#xff0c;配置添加SQL数据源。 创建SQL数据源连接 …

Django高效查询:values_list实战详解

Django 实战案例 讲解 values_list 的用法。 values_list("field", flatTrue) → 获取单字段的一维列表。values_list("f1", "f2") → 获取多个字段&#xff0c;返回元组。搭配 filter / distinct / in / 外键查询 非常高效。适合用于 导出数据 …

Java数据结构——树

一、树型结构1.1 概念我们之前提到的数组&#xff0c;单链表&#xff0c;栈和队列都是一种线性结构&#xff0c;每个元素都有最多一个后继节点。而树型结构是一种非线性结构&#xff0c;它是由n&#xff08;n>0&#xff09;节点组成的一个具有层次关系的集合。它之所以叫做树…

基于LLM的月全食时空建模与智能预测:从天文现象到深度学习融合

当古老的天文学遇上现代人工智能,会碰撞出怎样的火花? 一、当月球遇见AI 月全食,这一令人惊叹的天文现象,自古以来就吸引着无数天文学家和爱好者的目光。当地球恰好运行到太阳和月球之间,完全遮挡太阳光时,我们就能目睹月球逐渐被"吞噬"然后又重焕光彩的奇妙…

LeetCode热题 42.接雨水

题目 思路&#xff1a; 通过画图观察我们其实可以很容易发现&#xff0c;每个柱子接多少水由这个地方左边最高的柱子和右边最高的柱子确定&#xff0c;因为总要形成一个坑嘛&#xff0c;然后就能接着确定&#xff1a; 当前柱子接水量 min(左边最高柱子的高度, 右边最高柱子的…