[C/C++]基于标准库的C++ sqlite3常用功能封装和使用

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;
    }
}

本文实例Demo下载地址

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值