游客发表

MFC使用sqlite数据库

发帖时间:2026-10-17 04:39:02

MFC里操作SQLite,使e数最直接的据库路子是走C API。别绕弯子去封装什么C++类,使e数那层皮剥掉以后,据库你迟早得回来面对sqlite3_stmt这个结构体。使e数我见过太多人栽在封装上,据库最后调试时还得把封装层扒开看裸API。使e数

先讲打开数据库。据库sqlite3_open是使e数入口,但注意第二个参数是据库sqlite3**,得传指针的使e数地址。很多新手在这写错,据库传成sqlite3*,使e数编译能过,据库运行必崩。使e数打开后立刻检查返回值,SQLITE_OK是0,其他全是错误。我习惯写个小宏,把错误码和sqlite3_errmsg一起打印出来,省得每次重复劳动。

真正的重头戏是执行SQL。sqlite3_exec适合一次性跑完的语句,比如建表、插入批量数据。但查询就别用它了,回调函数那套写法在MFC里简直折磨人——你得把this指针塞进void*参数里,再在静态回调函数里强转回来。绕这么大圈子,不如直接用sqlite3_prepare_v2。这函数把SQL编译成字节码,返回一个stmt句柄,后面用sqlite3_step逐行取数据,用sqlite3_column_text按列索引取值。整个过程是命令式的,跟MFC的消息循环气质很搭。

参数绑定是个坑。拼SQL字符串往里塞值,一旦字段里带单引号,你就等着出错吧。正确姿势是用问号占位符,然后调sqlite3_bind_text、sqlite3_bind_int这些函数。注意索引从1开始,不是0。我踩过这个坑,查了半天才发现是索引错了。绑定完参数,每次执行完要调sqlite3_reset重置stmt,才能再次绑定新值。这个循环很机械,但必须严谨。

事务处理在MFC里尤其重要。SQLite默认是自动提交模式,每执行一条写操作就落盘一次。你要是循环插入一万条记录,那速度慢得能让你怀疑人生。解决办法是手动开事务:先执行"BEGIN",批量插入,最后"COMMIT"。中间出错就"ROLLBACK"。实测下来,有事务和没事务能差出两个数量级。这个优化比任何代码技巧都管用,而且实现起来就三行SQL的事。

内存管理别大意。sqlite3_stmt用完必须调sqlite3_finalize释放,否则内存泄漏。数据库连接用完调sqlite3_close。MFC程序经常长时间运行,泄漏一点内存积少成多,最后程序越来越卡。我习惯在析构函数里统一清理,但要注意清理顺序——先finalize所有stmt,再close数据库。

多线程访问是个麻烦事。SQLite默认编译选项下,同一个连接不能跨线程使用。MFC界面线程和工作线程分开,你要是直接在按钮事件里开个线程去查数据库,多半会碰到SQLITE_MISUSE错误。解决办法是每个线程单独开连接,或者编译SQLite时开启SQLITE_THREADSAFE。我通常选后者,省心。但开启后仍要小心,写操作还是得串行化,不然会撞上数据库锁。

最后说个细节。SQLite的磁盘文件会随着删除数据变大,不会自动收缩。你频繁增删后,文件体积可能远大于实际数据量。用VACUUM命令能重建数据库文件,释放空闲页。但这操作会锁库,别在高峰期执行。我一般安排在程序退出前,或者在后台空闲时处理。

这套流程跑通了,SQLite在MFC里就是个称手的工具。别指望它是什么重型数据库,但单机应用、配置存储、本地缓存这些场景,它比Access轻快,比写文件靠谱。关键是别被那些花哨的封装库迷惑,裸API已经够用了。

    热门排行

    友情链接