首页 > 投稿 > 正文内容

MFC中使用C++操作SQLite数据库保存数据的详细步骤

投稿2025-05-27 17:31:21

各位刚入坑MFC的小伙伴们,是不是总觉得数据库操作像在迷宫里找出口?今天咱们就用人话唠唠怎么用C++玩转SQLite存数据。先问个扎心的问题:你写的程序关闭后,那些用户输入的重要数据是不是都像被黑洞吸走了?别慌,看完这篇包你存数据比存钱还稳当!


一、准备工具就像备年货

咱们得先整点家伙事儿。SQLite官网下个最新版的sqlite3.dll,这玩意儿就像数据库的发动机。重点来了!把下载的sqlite3.h、sqlite3.lib、sqlite3.dll三个文件分别扔到:

  • 头文件放VS安装目录的VC\include文件夹
  • lib文件放VC\lib文件夹
  • dll文件放项目debug目录里

这时候可能有人要拍大腿:这配置也太麻烦了吧?其实就像装新游戏,把安装包放对位置就能启动。建议新手直接复制这三个文件到项目文件夹,保准编译器能找到。


二、连接数据库比连WiFi简单

打开VS新建个MFC对话框项目,先做件重要的事——在stdafx.h里加这句:

cpp复制
#include "sqlite3.h"
#pragma comment(lib, "sqlite3.lib")

这就好比给程序装上了数据库驱动。接着在按钮点击事件里写连接代码:

cpp复制
sqlite3* db;
int res = sqlite3_open("mydata.db", &db);
if(res != SQLITE_OK) {
    MessageBox(_T("数据库连接失败!"));
    return;
}

新手常见坑:数据库路径别写中文!有次我手贱用"测试数据.db"当文件名,结果程序直接罢工给你看。


三、建表就像搭积木

存数据得先有地方放对吧?咱们建个学生信息表练手:

cpp复制
char* sql = "CREATE TABLE IF NOT EXISTS students("
            "id INTEGER PRIMARY KEY AUTOINCREMENT,"
            "name TEXT NOT NULL,"
            "score REAL);";
char* errMsg = 0;
res = sqlite3_exec(db, sql, 0, 0, &errMsg);

这里有几个重点:

  1. ??IF NOT EXISTS?? 防止重复建表报错
  2. ??AUTOINCREMENT?? 让ID自动增长
  3. ??TEXT和REAL?? 对应字符串和浮点数

有小白要问:为啥不用int存分数?因为可能有89.5这种带小数的情况啊!咱们得考虑实际情况。


四、存数据比发快递靠谱

最关键的插入操作来了!这里推荐用预处理语句,比直接拼接SQL语句安全十倍:

cpp复制
sqlite3_stmt* stmt;
const char* sql = "INSERT INTO students(name,score) VALUES(?,?);";
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);

// 绑定参数
CString strName = _T("张三");
double dScore = 88.5;
sqlite3_bind_text(stmt, 1, CW2A(strName), -1, SQLITE_TRANSIENT);
sqlite3_bind_double(stmt, 2, dScore);

// 执行插入
res = sqlite3_step(stmt);
if(res == SQLITE_DONE) {
    MessageBox(_T("存数据成功!"));
}
sqlite3_finalize(stmt);

注意这个问号占位符?就像快递单上的收件人信息栏,后面再填具体内容。这样做能防SQL注入攻击,比直接拼接字符串安全得多。


五、查数据比翻聊天记录容易

存进去的数据得能查出来才算数。咱们写个查询所有数据的例子:

cpp复制
const char* sql = "SELECT * FROM students;";
sqlite3_stmt* stmt;
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);

CString strResult;
while(sqlite3_step(stmt) == SQLITE_ROW) {
    int id = sqlite3_column_int(stmt, 0);
    const char* name = (const char*)sqlite3_column_text(stmt, 1);
    double score = sqlite3_column_double(stmt, 2);
    
    strResult.Format(_T("学号:%d 姓名:%s 分数:%.1f\r\n"), 
                    id, CA2W(name), score);
    // 显示到列表框或文本框
}
sqlite3_finalize(stmt);

新手容易栽跟头的地方:查完数据一定要调用sqlite3_finalize,不然内存泄漏能让你程序越跑越慢,最后直接卡成PPT。


六、避坑指南(血泪教训)

  1. 数据库操作完必须调用??sqlite3_close??,否则文件会被锁定打不开
  2. 多线程操作要加锁,建议新手先用单线程练手
  3. 遇到错误码别慌,用??sqlite3_errmsg(db)?? 能直接看到错误描述
  4. 重要数据记得定期备份,直接复制.db文件就行

有次我忘记关数据库连接,第二天发现程序启动就报错,最后发现是.db文件被锁住了。这教训值千金啊!


七、性能优化小妙招

当数据量超过1万条时,记得在插入前加上这两句:

cpp复制
sqlite3_exec(db, "BEGIN TRANSACTION;", 0, 0, 0);
// 批量插入操作...
sqlite3_exec(db, "COMMIT TRANSACTION;", 0, 0, 0);

这样操作速度能提升几十倍!原理就像寄快递,把100个包裹打包一起寄,肯定比一个个寄快多了。


小编观点:新手刚开始建议先用SQLiteSpy这个可视化工具查看数据库,比纯代码调试直观十倍。记住,存数据就像存钱,既要存得进去,取得出来,更要保证安全。别总想着一步到位,先把基础操作玩溜了,再研究事务、触发器这些高级玩法更靠谱!

搜索