SQLite
SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。
本文实现对SQLite常用功能的封装,如:增,删,改,查,事务。
文章底部提供实例下载(VS2013),下面是关键函数讲解
代码
连接数库
dbname是数据库名称,成功返回sqlite3指针。
// 如果dbname为空或者连接数据库失败,返回NULL
sqlite3* open(const char *dbname)
{
if (strcmp("", dbname) == 0 || !dbname)
return NULL;
sqlite3 *pSqlite = NULL;
if (sqlite3_open(dbname, &pSqlite) != SQLITE_OK)
fprintf(stderr, "连接数据库失败:%s\n", sqlite3_errmsg(pSqlite));
else {
fprintf(stderr, "连接数据库成功\n");
}
return pSqlite;
}
使用实例,连接数据库smb.db
sqlite3 *db = NULL;
extern "C" void InitializeDB()
{
if (!db)
db = open("smb.db");
}
创建表
参数sql是create table 语句
int createTable(sqlite3 *p, const char *sql)
{
if (!p || strcmp("", sql) == 0 || !sql)
return 0;
int result;
char *zErrorMsg = NULL;
if (sqlite3_exec(p, sql, 0, 0, &zErrorMsg) != SQLITE_OK) {
printf("创建表失败, 错误信息:%s\n", zErrorMsg);
result = 0;
}
else
result = 1;
sqlite3_free(zErrorMsg);
return result;
}
使用实例,创建login表
// 如果登陆表不存在,自动创建
int CreateLoginTable()
{
InitializeDB();
const char *sql = "CREATE TABLE login (" \
"id INTEGER PRIMARY KEY AUTOINCREMENT," \
"account CHAR(50) NOT NULL," \
"password CHAR(50) NOT NULL," \
"pwd_state INT);";
int tableIsExits = isTableExits(db, "login");
if (tableIsExits == -1) // 判断表存在失败
return 0;
else if (tableIsExits == 0) {// 表不存在
if (createTable(db, sql) == 0) // 创建表失败
return 0;
} // end if
return 1;
}
表操作
表操作包含增,删,改。统一封装一个update函数
int update(sqlite3 *p, const char *sql)
{
if (!p || strcmp("", sql) == 0 || !sql)
return 0;
int result;
char *zErrorMsg = NULL;
if (sqlite3_exec(p, sql, 0, 0, &zErrorMsg) != SQLITE_OK) {
printf("添加或修改或删除操作失败, 错误信息:%s\n", zErrorMsg);
result = 0;
}
else
result = 1;
sqlite3_free(zErrorMsg);
return result;
}
表字段
login表字段封装成结构体,如下
typedef struct Login
{
Login() { memset(this, 0, sizeof(Login)); };
char *account; // 登陆用户名
char *password; // 密码
int pwd_state; // 是否记住密码,1记住,0不记住
} login_t;
实例如下:
增
extern "C" int AddItemToLoginTable(login_t login)
{
if (!CreateLoginTable())
return 0;
if (!DeleteLoginTable(1))
return 0;
char state[10];
char sql[512] = "INSERT INTO login (" \
"id, account, password, pwd_state)" \
"VALUES (1,";
strcat_s(sql, "'");
strcat_s(sql, login.account);
strcat_s(sql, "', '");
strcat_s(sql, login.password);
strcat_s(sql, "', '");
sprintf_s(state, "%d", login.pwd_state);
strcat_s(sql, state);
strcat_s(sql, "')");
if (!update(db, sql))
return 0;
return 1;
}
删
int DeleteLoginTable(int id)
{
char idstr[10];
char sql[100] = "DELETE FROM login WHERE id = ";
sprintf_s(idstr, "%d", id);
strcat_s(sql, idstr);
if (!update(db, sql))
return 0;
return 1;
}
改(略)
同 增
查询
查询就要有结果集,先设计一个存放结果的结构体,如下
// 封装返回值
typedef struct QureyResult
{
int n_row;
int n_column;
int n_index;
char** p_result;
QureyResult(int row, int column, char**p) {
n_row = row;
n_column = column;
p_result = NULL;
n_index = 0;
if (n_row > 0)
p_result = p;
} // end QueryResult
~QureyResult() {
if (p_result)
sqlite3_free_table(p_result);
}
bool next() {
if (n_index == 0) {
if (n_row > 0) {
++n_index;
return true;
}
else
return false;
}
else {
if ((n_row * n_column) >= ((n_index + 1) * n_column)) {
++n_index;
return true;
}
else
return false;
} // end else
}
char* value(char *pColumnName) {
int index = n_index * n_column;
for (int i = 0; i < n_column; ++i) {
if (strcmp(pColumnName, p_result[i]) == 0)
return p_result[index];
++index;
}
return NULL;
}
} query_result_t;
查
query_result_t* query(sqlite3 *p, const char *sql)
{
if (!p || strcmp("", sql) == 0 || !sql)
return 0;
query_result_t *query_result = NULL;
char *zErrorMsg = NULL;
char **dbResult;
int nRow = 0;
int nColumn = 0;
if (sqlite3_get_table(p, sql, &dbResult, &nRow, &nColumn, &zErrorMsg) != SQLITE_OK)
printf("查询失败, 错误信息:%s\n", zErrorMsg);
else
query_result = new query_result_t(nRow, nColumn, dbResult);
sqlite3_free(zErrorMsg);
return query_result;
}
实例,login_t结构体指向一个储存结果集的返回值指针
extern "C" void GetItemFromLoginTable(login_t *login)
{
query_result_t *qrt = NULL;
char sql[100] = { 0 };
strcpy_s(sql, "SELECT id, account, password, pwd_state FROM login WHERE id = 1");
qrt = query(db, sql);
if (qrt && qrt->next()) {
login->account = (char *)malloc(strlen(qrt->value("account")) + 1);
strcpy_s(login->account, strlen(qrt->value("account")) + 1, qrt->value("account"));
login->password = (char *)malloc(strlen(qrt->value("password")) + 1);
strcpy_s(login->password, strlen(qrt->value("password")) + 1, qrt->value("password"));
login->pwd_state = atoi(qrt->value("pwd_state"));
delete(qrt);
}
}
切记释放结构体指针
extern "C" void CleanLogin(login_t *login)
{
if (NULL != login->account) {
free(login->account);
}
if (NULL != login->password) {
free(login->password);
}
}
事务
开启事务
int transaction(sqlite3 *p)
{
if (!p)
return 0;
int result;
char *zErrorMsg = NULL;
int ret = sqlite3_exec(p, "begin transaction", 0, 0, &zErrorMsg); // 开始一个事务
if (ret != SQLITE_OK) {
printf("开始事务失败, 错误信息:%s\n", zErrorMsg);
result = 0;
}
else
result = 1;
sqlite3_free(zErrorMsg);
return result;
}
提交事务
int commitTransaction(sqlite3 *p)
{
if (!p)
return 0;
int result;
char *zErrorMsg = NULL;
int ret = sqlite3_exec(p, "commit transaction", 0, 0, &zErrorMsg); // 开始一个事务
if (ret != SQLITE_OK) {
printf("提交事务失败, 错误信息:%s\n", zErrorMsg);
result = 0;
}
else
result = 1;
sqlite3_free(zErrorMsg);
return result;
}
事务回滚
int rollbackTransaction(sqlite3 *p)
{
if (!p)
return 0;
int result;
char *zErrorMsg = NULL;
int ret = sqlite3_exec(p, "rollback transaction", 0, 0, &zErrorMsg); // 开始一个事务
if (ret != SQLITE_OK) {
printf("回滚事务失败, 错误信息:%s\n", zErrorMsg);
result = 0;
}
else
result = 1;
sqlite3_free(zErrorMsg);
return result;
}
关闭数据库
void close(sqlite3 *p)
{
if (p) {
sqlite3_close(p);
p = NULL;
}
}