235 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			235 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								### 使用c++11封装sqlite库
							 | 
						|||
| 
								 | 
							
								#### 13.1 sqlite基本用法
							 | 
						|||
| 
								 | 
							
								对于带参数的sql语句:<br>
							 | 
						|||
| 
								 | 
							
								其中sqlite3_perpare_v2用于解析sql文本并且保存到sqlite_stmt对象中,sqlite3_stmt将作为后面一些函数的入参;sqlite3_bind_XXX用于绑定sql文本中的参数
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								#include <sqlite3.h>
							 | 
						|||
| 
								 | 
							
								#include <string>
							 | 
						|||
| 
								 | 
							
								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<colCount;++i)
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        int coltype=sqlite3_column_type(stmt,i);
							 | 
						|||
| 
								 | 
							
								        if(coltype==SQLITE_INTEGER)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            int val=sqlite3_column_int(stmt,i);
							 | 
						|||
| 
								 | 
							
								        }else if(coltype==SQLITE_FLOAT)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            double val=sqlite3_column_double(stmt,i);
							 | 
						|||
| 
								 | 
							
								        }else if(coltype==SQLITE_TEXT)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            const char* val=(const char*)sqlite3_column_text(stmt,i);
							 | 
						|||
| 
								 | 
							
								        }else if(coltype==SQLITE_NULL)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								sqlite3_finalize(stmt);
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								事务
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								sqlite3_exec(dbHandle,"BEGIN");
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								sqlite3_exec(dbHandle,"ROLLBACK");
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								sqlite3_exec(dbHandle,"COMMIT");
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								sqlite3_exec(dbHandle,"END");
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
									* 不带占位符。执行sql,不带返回结果, 如insert,update,delete等
							 | 
						|||
| 
								 | 
							
									* @param[in] query: sql语句, 不带占位符
							 | 
						|||
| 
								 | 
							
									* @return bool, 成功返回true,否则返回false
							 | 
						|||
| 
								 | 
							
									*/
							 | 
						|||
| 
								 | 
							
									bool Excecute(const string& sqlStr)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										m_code = sqlite3_exec(m_dbHandle, sqlStr.data(), nullptr, nullptr, nullptr);
							 | 
						|||
| 
								 | 
							
										return SQLITE_OK == m_code;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/**
							 | 
						|||
| 
								 | 
							
									* 带占位符。执行sql,不带返回结果, 如insert,update,delete等
							 | 
						|||
| 
								 | 
							
									* @param[in] query: sql语句, 可能带占位符"?"
							 | 
						|||
| 
								 | 
							
									* @param[in] args: 参数列表,用来填充占位符
							 | 
						|||
| 
								 | 
							
									* @return bool, 成功返回true,否则返回false
							 | 
						|||
| 
								 | 
							
									*/
							 | 
						|||
| 
								 | 
							
									template <typename... Args>
							 | 
						|||
| 
								 | 
							
									bool Excecute(const string& sqlStr, Args && ... args)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										if (!Prepare(sqlStr))
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											return false;
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										return ExcecuteArgs(std::forward<Args>(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 <typename... Args>
							 | 
						|||
| 
								 | 
							
									bool ExcecuteArgs(Args && ... args)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										if (SQLITE_OK != detail::BindParams(m_statement, 1, std::forward<Args>(args)...))
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											return false;
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										m_code = sqlite3_step(m_statement);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										sqlite3_reset(m_statement);
							 | 
						|||
| 
								 | 
							
										return m_code == SQLITE_DONE;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									template<typename Tuple>
							 | 
						|||
| 
								 | 
							
									bool ExcecuteTuple(const string& sqlStr, Tuple&& t)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										if (!Prepare(sqlStr))
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											return false;
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										m_code = detail::ExcecuteTuple(m_statement, detail::MakeIndexes<std::tuple_size<Tuple>::value>::type(), std::forward<Tuple>(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<R>();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										if (SQLITE_OK != detail::BindParams(m_statement, 1, std::forward<Args>(args)...))
							 | 
						|||
| 
								 | 
							
										{
							 | 
						|||
| 
								 | 
							
											return GetErrorVal<R>();
							 | 
						|||
| 
								 | 
							
										}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										m_code = sqlite3_step(m_statement);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										if (m_code != SQLITE_ROW)
							 | 
						|||
| 
								 | 
							
											return GetErrorVal<R>();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										SqliteValue val = GetValue(m_statement, 0);
							 | 
						|||
| 
								 | 
							
										R result = val.Get<R>();// get<R>(val);
							 | 
						|||
| 
								 | 
							
										sqlite3_reset(m_statement);
							 | 
						|||
| 
								 | 
							
										return result;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									template <typename... Args>
							 | 
						|||
| 
								 | 
							
									std::shared_ptr<rapidjson::Document> Query(const string& query, Args&&... args)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										if (!PrepareStatement(query, std::forward<Args>(args)...))
							 | 
						|||
| 
								 | 
							
											nullptr;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										auto doc = std::make_shared<rapidjson::Document>();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										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
							 |