首页 5G技术

C++ 实战:巧用 SQLite3 打造轻量级数据库应用

分类:5G技术
字数: (0453)
阅读: (1233)
内容摘要:C++ 实战:巧用 SQLite3 打造轻量级数据库应用,

在使用 C++ 进行应用开发时,经常需要处理数据存储的问题。对于一些轻量级的应用,如嵌入式系统、小型桌面应用等,使用重量级的数据库系统(如 MySQL, PostgreSQL)显得过于复杂和资源消耗过大。这时,SQLite3 就成为了一个理想的选择。本文将深入探讨 C++ 邂逅 SQLite3 的实践方法,从底层原理到具体代码实现,再到实战避坑,力求为你提供全方位的指南。

SQLite3 数据库底层原理浅析

SQLite3 是一个轻量级的、自包含的、无服务器的、零配置的事务型 SQL 数据库引擎。它以文件形式存储数据,无需单独的服务器进程。它的主要特点包括:

  • 无服务器架构:SQLite3 不需要单独的服务器进程,直接读写磁盘文件。这简化了部署和管理,特别适合嵌入式环境。
  • 事务支持:SQLite3 支持 ACID 事务,保证数据的完整性和一致性。
  • 跨平台:SQLite3 可以在多种操作系统上运行,包括 Windows, Linux, macOS 等。
  • SQL 标准支持:SQLite3 支持大部分 SQL 标准,方便开发者使用熟悉的 SQL 语句进行数据操作。

SQLite3 核心概念

了解 SQLite3 的底层原理有助于我们更好地使用它。SQLite3 的核心概念包括:

C++ 实战:巧用 SQLite3 打造轻量级数据库应用
  • 数据库文件:所有数据都存储在一个单独的文件中。
  • 表(Table):用于组织数据的基本结构,包含行(Row)和列(Column)。
  • 索引(Index):用于加速数据检索,类似于书籍的目录。
  • 事务(Transaction):一组 SQL 操作,要么全部成功,要么全部失败。

SQLite3 与 MySQL 的对比

特性SQLite3MySQL
架构无服务器客户端/服务器
数据存储单个文件多个文件或目录
并发较低,适合单用户或低并发场景较高,适合高并发场景
资源消耗较小较大
适用场景嵌入式系统、小型桌面应用、移动应用等大型 Web 应用、企业级应用等

C++ 操作 SQLite3 的代码实现

接下来,我们将通过 C++ 代码演示如何操作 SQLite3 数据库。我们需要先安装 SQLite3 的 C++ 库。在 Linux 环境下,可以使用以下命令安装:

sudo apt-get update
sudo apt-get install libsqlite3-dev

连接数据库

首先,我们需要包含 SQLite3 的头文件,并连接到数据库:

C++ 实战:巧用 SQLite3 打造轻量级数据库应用
#include <iostream>
#include <sqlite3.h>

int main() {
    sqlite3 *db;
    int rc = sqlite3_open("test.db", &db); // 打开或创建数据库文件

    if (rc) {
        std::cerr << "Can't open database: " << sqlite3_errmsg(db) << std::endl;
        return 1;
    } else {
        std::cout << "Opened database successfully\n";
    }

    sqlite3_close(db); // 关闭数据库连接
    return 0;
}

创建表

接下来,我们可以创建一个表来存储数据:

#include <iostream>
#include <sqlite3.h>

int main() {
    sqlite3 *db;
    char *errMsg = 0;
    int rc = sqlite3_open("test.db", &db);

    if (rc) {
        std::cerr << "Can't open database: " << sqlite3_errmsg(db) << std::endl;
        return 1;
    }

    const char *sql = "CREATE TABLE IF NOT EXISTS COMPANY(\n"  // 创建表 SQL 语句
                       "ID INT PRIMARY KEY     NOT NULL,\n"
                       "NAME           TEXT    NOT NULL,\n"
                       "AGE            INT     NOT NULL,\n"
                       "ADDRESS        CHAR(50),\n"
                       "SALARY         REAL);";

    rc = sqlite3_exec(db, sql, 0, 0, &errMsg); // 执行 SQL 语句

    if (rc != SQLITE_OK) {
        std::cerr << "SQL error: " << errMsg << std::endl;
        sqlite3_free(errMsg); // 释放错误信息
    } else {
        std::cout << "Table created successfully\n";
    }

    sqlite3_close(db);
    return 0;
}

插入数据

现在,我们可以向表中插入一些数据:

C++ 实战:巧用 SQLite3 打造轻量级数据库应用
#include <iostream>
#include <sqlite3.h>

int main() {
    sqlite3 *db;
    char *errMsg = 0;
    int rc = sqlite3_open("test.db", &db);

    if (rc) {
        std::cerr << "Can't open database: " << sqlite3_errmsg(db) << std::endl;
        return 1;
    }

    const char *sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  // 插入数据 SQL 语句
                       "VALUES (1, 'Paul', 32, 'California', 20000.00 ); "
                       "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
                       "VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); "
                       "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
                       "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 ); "
                       "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
                       "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";

    rc = sqlite3_exec(db, sql, 0, 0, &errMsg);

    if (rc != SQLITE_OK) {
        std::cerr << "SQL error: " << errMsg << std::endl;
        sqlite3_free(errMsg);
    } else {
        std::cout << "Records created successfully\n";
    }

    sqlite3_close(db);
    return 0;
}

查询数据

最后,我们可以查询表中的数据:

#include <iostream>
#include <sqlite3.h>

static int callback(void *NotUsed, int argc, char **argv, char **azColName) {
    int i;
    for (i = 0; i < argc; i++) {
        std::cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL") << std::endl;
    }
    std::cout << std::endl;
    return 0;
}

int main() {
    sqlite3 *db;
    char *errMsg = 0;
    int rc = sqlite3_open("test.db", &db);

    if (rc) {
        std::cerr << "Can't open database: " << sqlite3_errmsg(db) << std::endl;
        return 1;
    }

    const char *sql = "SELECT * FROM COMPANY"; // 查询数据 SQL 语句

    rc = sqlite3_exec(db, sql, callback, 0, &errMsg);

    if (rc != SQLITE_OK) {
        std::cerr << "SQL error: " << errMsg << std::endl;
        sqlite3_free(errMsg);
    } else {
        std::cout << "Operation done successfully\n";
    }

    sqlite3_close(db);
    return 0;
}

实战避坑经验总结

在使用 C++ 和 SQLite3 进行数据库编程时,有一些常见的坑需要注意:

C++ 实战:巧用 SQLite3 打造轻量级数据库应用
  • SQL 注入:避免直接拼接用户输入到 SQL 语句中,使用参数化查询(Prepared Statements)可以有效防止 SQL 注入攻击。
  • 资源泄漏:务必在使用完数据库连接后及时关闭,释放资源。
  • 错误处理:仔细检查 SQLite3 API 的返回值,及时处理错误情况。
  • 字符编码:确保 C++ 代码和 SQLite3 数据库使用相同的字符编码,避免乱码问题。特别是在涉及中文等非 ASCII 字符时,UTF-8 是一个不错的选择。
  • 事务管理:合理使用事务,确保数据的完整性和一致性。特别是在进行批量数据操作时,使用事务可以显著提高性能。
  • 锁机制:SQLite3 使用文件锁来实现并发控制。在高并发场景下,可能出现锁竞争,影响性能。可以考虑使用 WAL (Write-Ahead Logging) 模式来提高并发性能。

通过本文的介绍,相信你已经对 C++ 邂逅 SQLite3 有了更深入的了解。希望你能在实际项目中灵活运用 SQLite3,构建出高效、稳定的数据库应用。

C++ 实战:巧用 SQLite3 打造轻量级数据库应用

转载请注明出处: 代码一只喵

本文的链接地址: http://m.acea2.store/blog/920502.SHTML

本文最后 发布于2026-04-22 17:43:52,已经过了5天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 北京炸酱面 1 天前
    感谢分享,WAL 模式之前没用过,回头研究一下,看看能不能提高我们项目的并发性能。
  • 扬州炒饭 2 天前
    SQL 注入那个坑确实需要注意,之前就遇到过,差点被黑客搞了。
  • 单身狗 5 天前
    感谢分享,WAL 模式之前没用过,回头研究一下,看看能不能提高我们项目的并发性能。
  • 红豆沙 6 天前
    楼主写的很详细,正好最近在做一个小项目需要用到 C++ 和 SQLite3,这下有参考了。