PC端操作SQLite数据库

上一篇我把安卓应用的db文件导出来了。再试一下PC端操作这个数据库。

下载sqlite3.h , 链接 SQLite Download Page

下载下来解压,有如下文件:

我之前有个demo工程叫CppTest的,就用这个工程测试下,把sqlite3头文件和源文件分别放到include目录和src目录,db文件放入工程根目录,如下:

修改CMakeLists.txt,配置支持c语言, 如下:

bash 复制代码
# 最低CMake版本要求
cmake_minimum_required(VERSION 3.10)

# 项目名 + 语言
project(MyCppTestProject LANGUAGES CXX C)

# 设置C++标准 C++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 头文件目录(让编译器能找到include里的.h)
include_directories(include)

file(GLOB SRC_FILES
    *.cpp
    src/*.cpp
    src/*.c
)
# 过滤掉 CMake 编译器检测文件
list(FILTER SRC_FILES EXCLUDE REGEX "CMakeCXXCompilerId.cpp")

# 生成可执行文件,名字叫 main
add_executable(main ${SRC_FILES})

# 编译输出到 output 文件夹
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/output)

修改main.cpp, 测试下数据库:

cpp 复制代码
#include <iostream>
#include "MyVec.h"
extern "C" {
    #include "sqlite3.h"
}

using namespace std;

void testYunsuanfuChongZai();


/**
 * 查询回调函数:每查到一行数据就会触发
 */
 extern "C" int selectCallback(void* arg, int colCount, char** colValue, char** colName)
 {
     std::cout << "进入回调函数" << std::endl;
     std::cout << "-------- 单条数据 --------" << std::endl;
     for (int i = 0; i < colCount; ++i)
     {
         std::cout << colName[i] << " : " << (colValue[i] ? colValue[i] : "null") << std::endl;
     }
     return 0;
 }

 int testDB(void) {
    sqlite3* db = nullptr;
    // 使用绝对路径,确保文件存在
    const char* dbName = "E:/cpp/projects/CppTest/todo_database.db";
    int ret = sqlite3_open(dbName, &db);
    if (ret != SQLITE_OK) {
        std::cerr << "打开数据库失败:" << sqlite3_errmsg(db) << std::endl;
        return -1;
    }
    std::cout << "数据库打开成功" << std::endl;

    // 插入数据
    char* errMsg = nullptr;
    const char* insertSql = R"(
        INSERT INTO account (accountName, password, nickName, note, address)
        VALUES ('test001', '666888', '测试用户', 'C++写入', '测试地址');
    )";
    ret = sqlite3_exec(db, insertSql, nullptr, nullptr, &errMsg);
    if (ret != SQLITE_OK) {
        std::cerr << "插入失败:" << errMsg << std::endl;
        sqlite3_free(errMsg);
        sqlite3_close(db);
        return -1;
    }
    std::cout << "数据插入成功" << std::endl;

    /*
    const char* selectSql = "SELECT * FROM account;";
    std::cout << "===== 查询所有数据 =====" << std::endl;
    ret = sqlite3_exec(db, selectSql, selectCallback, nullptr, &errMsg);
    if (ret != SQLITE_OK)
    {
        std::cerr << "查询数据失败:" << errMsg << std::endl;
        if (errMsg != nullptr)
        {
            sqlite3_free(errMsg);
        }
    }
    */

    // 查询所有数据(使用 prepare + step,最安全)
    sqlite3_stmt* stmt = nullptr;
    const char* selectSql = "SELECT id, accountName, password, nickName, note, address FROM account;";
    ret = sqlite3_prepare_v2(db, selectSql, -1, &stmt, nullptr);
    if (ret != SQLITE_OK) {
        std::cerr << "准备查询语句失败:" << sqlite3_errmsg(db) << std::endl;
        sqlite3_close(db);
        return -1;
    }

    std::cout << "\n===== 查询结果 =====" << std::endl;
    int rowCount = 0;
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        rowCount++;
        std::cout << "-------- 第 " << rowCount << " 条 --------" << std::endl;
        int id = sqlite3_column_int(stmt, 0);
        const unsigned char* accountName = sqlite3_column_text(stmt, 1);
        const unsigned char* password = sqlite3_column_text(stmt, 2);
        const unsigned char* nickName = sqlite3_column_text(stmt, 3);
        const unsigned char* note = sqlite3_column_text(stmt, 4);
        const unsigned char* address = sqlite3_column_text(stmt, 5);

        std::cout << "id: " << id << std::endl;
        std::cout << "accountName: " << (accountName ? (const char*)accountName : "NULL") << std::endl;
        std::cout << "password: " << (password ? (const char*)password : "NULL") << std::endl;
        std::cout << "nickName: " << (nickName ? (const char*)nickName : "NULL") << std::endl;
        std::cout << "note: " << (note ? (const char*)note : "NULL") << std::endl;
        std::cout << "address: " << (address ? (const char*)address : "NULL") << std::endl;
        std::cout.flush();  // 强制输出
    }
    sqlite3_finalize(stmt);

    if (rowCount == 0) {
        std::cout << "表中没有数据" << std::endl;
    }

    sqlite3_close(db);
    std::cout << "数据库已关闭" << std::endl;
    return 0;
}

int main()
{
    setvbuf(stdout, nullptr, _IONBF, 0);   // 完全禁用输出缓冲
    system("chcp 65001"); // 控制台输出用UTF-8
    cout << "VSCode C++ 环境正常. ok" << endl;
    // 打印 C++ 标准版本
    cout << "当前 C++ 标准版本: " << __cplusplus << endl;

    // 显示名称
    if (__cplusplus == 201103L) cout << "=> C++11\n";
    else if (__cplusplus == 201402L) cout << "=> C++14\n";
    else if (__cplusplus == 201703L) cout << "=> C++17\n";
    else if (__cplusplus == 202002L) cout << "=> C++20\n";
    else if (__cplusplus == 202302L) cout << "=> C++23\n";

    testYunsuanfuChongZai();

    cout << "ok ........................." << endl;

    testDB();
    return 0;
}

void testYunsuanfuChongZai() { // 测试运算符重载
	MyVec v1(1,2);
	MyVec v2(4); // 第二个参数有默认值0,可以不传
	MyVec v3 = v1 + v2;
	cout << v3 << endl;
	cout << "v3.x: " << v3[0] << ", v3.y: " << v3[1] << endl;
}

编译之前,先执行下面命令生成Makefile:

cmake -G "MinGW Makefiles" .

再执行 mingw32-make 编译所有文件。

然后运行,打印如下:

看着有些日志没打印,重试好多次都是。 用DB Browser for SQLite工具打开这个db文件,查看下account表:

ok. 看着数据已经插入成功了。不知道为啥日志打印不全。 之前是在VS Code的控制台执行的,改为新开一个cmd窗口执行,输出如下:

ok. 说明程序是没问题的。只是日志打印有问题。先不管了。提交下代码。先看下状态:

其中有些是不用提交的。在工程根目录新建 .gitignore 文件,内容如下:

bash 复制代码
# CMake 缓存 & 构建文件
CMakeCache.txt
CMakeFiles/
Makefile
*.cmake
*.rsp
*.marks

# 编译产物
output/
*.exe
*.obj
*.o
*.a
*.lib
*.dll

# 日志、系统垃圾文件
*.log
.DS_Store
Thumbs.db

再执行:

git add .gitignore CMakeLists.txt main.cpp include/ src/ todo_database.db

提交,推送到gitee:

ok. 查看下gitee页面:

ok. 但是远程仓库有不需要的文件,即本地编译产物(CMakeCache.txt、CMakeFiles、Makefile、output/ 等)。

先把这些 "编译垃圾" 从 Git 跟踪里删掉(本地保留)

其中:

--cached:只删 Git 记录,本地文件还在,不影响你编译

-r:递归删文件夹

提交删除操作:

推送:

再看下 gitee该仓库:

ok. 现在不需要提交的文件删除了。

相关推荐
MXsoft6181 小时前
**采集节点主备模:保障监控系统自身高可用**
数据库
CHHH_HHH1 小时前
【C++】哈希表原理与实战:从冲突解决到性能优化
开发语言·数据结构·c++·学习·算法·哈希算法·散列表
winfredzhang1 小时前
用 wxPython + 通义千问 VL 打造一款“批量人物图像识别“桌面应用
python·sqlite·wxpython·qwen 3.7max·分析照片
fpcc1 小时前
并行编程实战——CUDA编程的pipelines
c++·cuda
Tairitsu_H2 小时前
[LC优选算法#5] 分治:快排 | 颜色分类 | 排序数组 | 第K大元素
c++·算法·leetcode·排序算法·快速排序
yyuuuzz2 小时前
独立站运营的几个技术层面常见问题
大数据·运维·服务器·网络·数据库·aws
Frank学习路上2 小时前
【C++】面试:STL容器与算法
c++·算法·面试
凡人叶枫2 小时前
Effective C++ 条款33:避免遮掩继承而来的名字
linux·服务器·开发语言·c++·嵌入式开发
10岁的博客2 小时前
NOIP2010普及组「接水问题」详解:模拟算法与优先队列解法
开发语言·c++·算法