eduwin + SQLite 数据库编程
SQLite 是一个自包含、零配置、嵌入式的 C 语言数据库引擎。eduwin 已将 SQLite 编译进 eduwin.lib,学生程序只需 #include "sqlite3.h" 即可直接使用,无需额外配置。
快速开始
#include "eduwin.h"
#include "sqlite3.h"
int main(void)
{
init_app();
sqlite3 *db = NULL;
int rc = sqlite3_open("test.db", &db);
if (rc != SQLITE_OK)
{
alert(L"错误", L"无法打开数据库");
return 1;
}
char *err = NULL;
sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS users ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT NOT NULL, "
"email TEXT)", NULL, NULL, &err);
if (err)
{
alert(L"错误", L"建表失败");
sqlite3_free(err);
}
HWND win = create_window(L"SQLite 测试", 500, 300);
show_window(win);
run_app();
sqlite3_close(db);
return 0;
}
编译命令:
build.bat
只要在 .c 文件中 #include "sqlite3.h",link 时自动从 eduwin.lib 获取 SQLite 实现。
核心 API
SQLite 最常用的三个函数:
打开/关闭
int sqlite3_open(const char *filename, sqlite3 **ppDb);
int sqlite3_close(sqlite3 *db);
sqlite3_open打开或创建数据库文件(UTF-8 路径)sqlite3_close关闭数据库,释放资源- 返回
SQLITE_OK(0)表示成功
执行 SQL
int sqlite3_exec(sqlite3 *db, const char *sql,
int (*callback)(void *, int, char **, char **),
void *data, char **errmsg);
最简单的执行方式——不需要回调时传 NULL:
sqlite3_exec(db, "INSERT INTO users VALUES(NULL, '张三', 'zhangsan@test.com')",
NULL, NULL, &err);
带参数查询(推荐)
/* 根据学号查询用户,返回姓名,未找到返回 NULL */
const char *find_user_name(sqlite3 *db, int user_id)
{
sqlite3_stmt *stmt = NULL;
/* 1. 准备 SQL(?是占位符) */
int rc = sqlite3_prepare_v2(db,
"SELECT name FROM users WHERE id = ?",
-1, &stmt, NULL);
if (rc != SQLITE_OK)
return NULL;
/* 2. 绑定参数(第 1 个 ? 绑定 user_id) */
sqlite3_bind_int(stmt, 1, user_id);
/* 3. 执行查询 */
const char *result = NULL;
if (sqlite3_step(stmt) == SQLITE_ROW)
{
/* 4. 读取结果集第 0 列 */
result = strdup((const char *)sqlite3_column_text(stmt, 0));
}
/* 5. 释放语句 */
sqlite3_finalize(stmt);
return result;
}
流程:准备 → 绑定 → 单步执行 → 读列 → 销毁。
? 是占位符,从 1 开始编号。多参数时:
/* UPDATE 示例:带三个占位符 */
sqlite3_stmt *stmt;
sqlite3_prepare_v2(db,
"UPDATE users SET name = ?, email = ? WHERE id = ?",
-1, &stmt, NULL);
sqlite3_bind_text(stmt, 1, name_utf8, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 2, email_utf8, -1, SQLITE_TRANSIENT);
sqlite3_bind_int(stmt, 3, user_id);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
始终使用参数绑定而非字符串拼接,可防止 SQL 注入。
获取最后插入的 ID
int last_id = (int)sqlite3_last_insert_rowid(db);
字符串编码
SQLite 的 API 使用 UTF-8 编码,而 eduwin 使用 UTF-16(宽字符)。eduwin 提供两个内置工具函数完成互转:
char *wtou8(const WCHAR *ws);
WCHAR *u8tow(const char *us);
wtou8:宽字符串 → UTF-8 字符串(malloc分配内存,用完需free)u8tow:UTF-8 字符串 → 宽字符串(malloc分配内存,用完需free)
这两个函数已编译在 eduwin.lib 中,#include "eduwin.h" 即可使用。
用法:
char *sql = wtou8(L"INSERT INTO users VALUES(NULL, '测试用户', 'test@test.com')");
sqlite3_exec(db, sql, NULL, NULL, &err);
free(sql);
const char *name8 = (const char *)sqlite3_column_text(stmt, 1);
WCHAR *name16 = u8tow(name8);
set_text(label, name16);
free(name16);
完整示例:用户管理
demo\sqlite_demo.c 是一个完整的用户信息管理程序,演示了增删改查全部操作,可直接编译运行(demo\build_sqlite_demo.bat):
功能包括:
- 列表显示所有用户(ListView)
- 添加用户(姓名、邮箱、电话)
- 双击列表项回填到输入框,修改后保存
- 选中用户后删除
- 实时搜索过滤