### 使用c++11封装sqlite库 #### 13.1 sqlite基本用法 对于带参数的sql语句:
其中sqlite3_perpare_v2用于解析sql文本并且保存到sqlite_stmt对象中,sqlite3_stmt将作为后面一些函数的入参;sqlite3_bind_XXX用于绑定sql文本中的参数 ``` #include #include bool test() { sqlite3* dbHandle = nullptr; int result = sqlite3_open("test.db", &dbHandle); if (result != SQLITE_OK) { sqlite3_close(dbHandle); return false; } const char* sqlcreat = "CREATE TABLE if not exists PersonTable(ID INTEGER NOT NULL, Name Text,Address BLOB);"; result = sqlite3_exec(dbHandle, sqlcreat, nullptr, nullptr, nullptr); //插入数据 sqlite3_stmt* stmt = NULL; const char* sqlinsert = "INSERT INTO PersonTable(ID,Name,Adress) VALUE(?,?,?);"; //解析并且保存sql脚本 sqlite3_prepare_v2(dbHandle, sqlinsert, strlen(sqlinsert), &stmt, nullptr); int id = 2; const char* name = "peter"; for (int i=0;i<10;++i) { sqlite3_bind_int(stmt, 1, id); sqlite3_bind_text(stmt, 2, name, strlen(name), SQLITE_TRANSIENT); sqlite3_bind_null(stmt, 3); if (sqlite3_step(stmt) != SQLITE_DONE) { sqlite3_finalize(stmt); sqlite3_close(dbHandle); } //重新初始化stmt对象,下次再用 sqlite3_reset(stmt); } //使用完需要释放,不然会内存泄露 sqlite3_finalize(stmt); sqlite3_close(dbHandle); return result = SQLITE_OK; } ``` 最后通过 sqlite3_colume_xxx(sqlite3_stmt*,int iCol)取得结果 ``` int colCount=sqlite3_column_count(stmt); while(true) { int r=sqlite3_step(stmt); if(r==SQLITE_DONE) { break;//数据行都已经获取,跳出循环 } if(r==SQLITE_ROW) { break;//获得某一行数据失败,跳出循环 } //获得每一列数据 for(int i=0;i bool Excecute(const string& sqlStr, Args && ... args) { if (!Prepare(sqlStr)) { return false; } return ExcecuteArgs(std::forward(args)...); } /** * 批量操作之前准备sql接口,必须和ExcecuteBulk一起调用,准备批量操作的sql,可能带占位符 * @param[in] query: sql语句, 带占位符"?" * @return bool, 成功返回true,否则返回false */ bool Prepare(const string& sqlStr) { m_code = sqlite3_prepare_v2(m_dbHandle, sqlStr.data(), -1, &m_statement, nullptr); if (m_code != SQLITE_OK) { return false; } return true; } /** * 批量操作接口,必须先调用Prepare接口 * @param[in] args: 参数列表 * @return bool, 成功返回true,否则返回false */ template bool ExcecuteArgs(Args && ... args) { if (SQLITE_OK != detail::BindParams(m_statement, 1, std::forward(args)...)) { return false; } m_code = sqlite3_step(m_statement); sqlite3_reset(m_statement); return m_code == SQLITE_DONE; } template bool ExcecuteTuple(const string& sqlStr, Tuple&& t) { if (!Prepare(sqlStr)) { return false; } m_code = detail::ExcecuteTuple(m_statement, detail::MakeIndexes::value>::type(), std::forward(t)); return m_code == SQLITE_DONE; } bool ExcecuteJson(const string& sqlStr, const char* json) { rapidjson::Document doc; doc.Parse<0>(json); if (doc.HasParseError()) { cout << doc.GetParseError() << endl; return false; } if (!Prepare(sqlStr)) { return false; } return JsonTransaction(doc); } /** * 执行sql,返回函数执行的一个值, 执行简单的汇聚函数,如select count(*), select max(*)等 * 返回结果可能有多种类型,返回Value类型,在外面通过get函数去取 * @param[in] query: sql语句, 可能带占位符"?" * @param[in] args: 参数列表,用来填充占位符 * @return int: 返回结果值,失败则返回-1 */ template < typename R = sqlite_int64, typename... Args> R ExecuteScalar(const string& sqlStr, Args&&... args) { if (!Prepare(sqlStr)) return GetErrorVal(); if (SQLITE_OK != detail::BindParams(m_statement, 1, std::forward(args)...)) { return GetErrorVal(); } m_code = sqlite3_step(m_statement); if (m_code != SQLITE_ROW) return GetErrorVal(); SqliteValue val = GetValue(m_statement, 0); R result = val.Get();// get(val); sqlite3_reset(m_statement); return result; } template std::shared_ptr Query(const string& query, Args&&... args) { if (!PrepareStatement(query, std::forward(args)...)) nullptr; auto doc = std::make_shared(); m_buf.Clear(); m_jsonHelper.BuildJsonObject(m_statement); doc->Parse<0>(m_buf.GetString()); return doc; } ``` 详细代码见 https://github.com/qicosmos/SmartDB1.03/blob/master/SmartDB.hpp