C++直接调用SQLite C接口需包含sqlite3.h、链接lib、检查返回值;用sqlite3_prepare_v2+bind防注入;设busy_timeout防卡死;批量操作用事务包裹;确保UTF-8字符串安全传递;每次错误后立即调用sqlite3_errmsg。
如何用 C++ 调用 SQLite 的 C 接口(不是 ORM)
SQLite 本身是 C 写的,官方只提供 C API;C++ 没有原生绑定,必须直接调用 sqlite3.h 中的函数。别找“C++ 封装库”——除非你明确需要 sqlite_modern_cpp 或 nanodbc 这类第三方,否则直接用 C 接口最轻、最稳、依赖最少。
关键步骤:包含头文件 + 链接 lib + 检查返回值。Windows 下需手动链接 sqlite3.lib(或用动态加载),Linux/macOS 用 -lsqlite3 即可。
-
sqlite3_open()返回非零值表示失败,务必检查,不要只看指针是否为nullptr - 所有 SQL 字符串建议用
sqlite3_exec()执行 DDL/DML(如CREATE TABLE),但注意它不支持参数绑定,仅适合固定语句 - 带用户输入的查询必须用
sqlite3_prepare_v2()+sqlite3_bind_*,否则必然 SQL 注入
为什么 sqlite3_step() 总卡在 SQLITE_BUSY?
这不是 bug,是 SQLite 默认的“阻塞式锁行为”。当另一个连接正在写事务时,读操作可能被挂起(尤其在 WAL 模式关闭时)。常见于多线程场景下未正确隔离连接或未设 busy timeout。
- 调用
sqlite3_busy_timeout(db, 5000)设置 5 秒重试上限(单位毫秒),这是最简单有效的缓解方式 - 避免在多个线程间共享同一个
sqlite3*句柄;每个线程应持有独立连接(sqlite3_open各开一个) - 确认是否启用了 WAL 模式:
PRAGMA journal_mode = WAL;—— 它能显著降低读写冲突,但要求数据库文件所在文件系统支持原子 rename
插入大量数据时性能骤降,怎么优化?
逐条执行 INSERT 是最慢的方式——每条语句都触发一次事务、日志刷盘和索引更新。瓶颈不在 C++ 代码,而在 SQLite 的默认事务粒度。