先编译生成静态库 然后复制库文件 和 sqlite3.h 头文件
需要项目配置一致
就配置好了 为什么不需要 sqlite3ext.h 是只有dll的情况 没有lib
有二种一种是偏向于API 容易移植 ,一种是偏向业务,
这个封装是是偏向于API的
sqlite.h
#pragma once
#include
#include
#include
#include "sqlite3.h"
#pragma comment(lib,"Sqlite.lib")
#ifdef _UNICODE
typedef std::wstring tstring;
#define SqliteOpen sqlite3_open16
#else
typedef std::string tstring;
#define SqliteOpen sqlite3_open
#endif // _UNICODE
class Sqlite
{
public:
Sqlite(const tstring& dbPath);
~Sqlite();
int Query(
const std::string& sql,
std::vector<std::vector<std::string>>& results,
std::vector<std::string>& cloumns,
std::string& strMsg);//查询
int QueryContainBlob(
const std::string& sql,
std::vector<std::vector<std::string>>& results,
std::vector<std::string>& cloumns,
std::string& strMsg);//查询
int Exec(const std::string& sql, std::string& strMsg);
protected:
static int SelectCallBackEntry(void* thiz, int argc, char* argv[], char* names[]);
int SelectCallBack(int argc, char* argv[], char* names[]);
int ClearResult();
private:
//不能复制构造 对象只有一个
Sqlite(const Sqlite& db) = delete;
Sqlite& operator=(const Sqlite& db) = delete;
private:
sqlite3* m_db;
sqlite3_stmt* m_stmt;
std::list<std::vector<std::string>*> m_result;
std::vector<std::string> m_cloumn;
};
sqlite.cpp
#include "Sqlite.h"
Sqlite::Sqlite(const tstring& dbPath)
{
m_stmt = NULL;
int ret= SqliteOpen(dbPath.c_str(), &m_db);
if (ret != 0)
{
throw ret;
}
}
Sqlite::~Sqlite()
{
ClearResult();
sqlite3* db = m_db;
m_db = NULL;
sqlite3_close(db);
}
int Sqlite::Query(
const std::string& sql,
std::vector<std::vector<std::string>>&results,
std::vector<std::string>& cloumns,
std::string&strMsg)
{
ClearResult();
char* errmsg = NULL;
int ret = sqlite3_exec(m_db, sql.c_str(), &Sqlite::SelectCallBackEntry, this, &errmsg);//只支持多字节
if (ret != SQLITE_OK)
{
strMsg = errmsg;
sqlite3_free(errmsg);
return ret;
}
results.resize(m_result.size());
if(m_result.size() > 0)
{
std::list<std::vector<std::string>*>::iterator it = m_result.begin();
for (size_t i = 0; (i < m_result.size())&& (it!=m_result.end()); i++,it++)
{
results[i].resize((*it)->size());
for (size_t j = 0; j < (*it)->size(); j++)
{
results[i][j] = (**it)[j];
}
}
}
cloumns.resize(m_cloumn.size());
for (size_t i = 0; i < m_cloumn.size(); i++)
{
cloumns[i] = m_cloumn[i];
}
return ret;
}
int Sqlite::QueryContainBlob(const std::string& sql,
std::vector<std::vector<std::string>>& results,
std::vector<std::string>& cloumns,
std::string& strMsg)
{
cloumns.clear();
ClearResult();
int ret=sqlite3_prepare(m_db, sql.c_str(),sql.size(), &m_stmt, NULL);//二进制处理
if (ret != SQLITE_OK)
{
strMsg = sqlite3_errmsg(m_db);
return ret;
}
while (sqlite3_step(m_stmt)==SQLITE_ROW)
{
int count = sqlite3_column_count(m_stmt);
if (count > 0 && cloumns.size() <= 0)
{
cloumns.resize(count);
for (size_t i = 0; i < count; i++)
{
cloumns[i]=sqlite3_column_name(m_stmt, i);
}
}
if (count > 0)
{
std::vector<std::string>* presult = new std::vector<std::string>;
presult->resize(count);
for (int i = 0; i < count; i++)
{
int type=sqlite3_column_type(m_stmt, i);
if ((type == SQLITE_BLOB))
{
(*presult)[i].resize(sqlite3_column_bytes(m_stmt, i));
memcpy((char*)(*presult)[i].c_str(), sqlite3_column_blob(m_stmt, i), (*presult)[i].size());
}
else
{
switch (type)
{
case SQLITE_INTEGER :
(*presult)[i] = std::to_string(sqlite3_column_int(m_stmt, i));
break;
case SQLITE_FLOAT:
(*presult)[i] =std::to_string(sqlite3_column_double(m_stmt, i));
break;
case SQLITE_NULL:
(*presult)[i] = "NULL";
break;
case SQLITE_TEXT:
(*presult)[i] = (char*)sqlite3_column_text(m_stmt, i);
break;
}
}
}
m_result.push_back(presult);
}
}
results.resize(m_result.size());
if (m_result.size() > 0)
{
std::list<std::vector<std::string>*>::iterator it = m_result.begin();
for (size_t i = 0; (i < m_result.size()) && (it != m_result.end()); i++, it++)
{
results[i].resize((*it)->size());
for (size_t j = 0; j < (*it)->size(); j++)
{
results[i][j] = (**it)[j];
}
}
}
sqlite3_finalize(m_stmt);
m_stmt = NULL;
return ret;
}
int Sqlite::Exec(const std::string& sql, std::string& strMsg)
{
char* errmsg = NULL;
int ret = sqlite3_exec(m_db, sql.c_str(), NULL, this, &errmsg);//只支持多字节
if (ret != SQLITE_OK)
{
strMsg = errmsg;
sqlite3_free(errmsg);
return ret;
}
return ret;
}
int Sqlite::SelectCallBackEntry(void* thiz, int argc, char* argv[], char* names[])
{
return ((Sqlite*)thiz)->SelectCallBack(argc, argv, names);
}
int Sqlite::SelectCallBack(int argc, char* argv[], char* names[])
{
if ((m_cloumn.size() == 0)&&(argc>0))
{
m_cloumn.resize(argc);
for (int i = 0; i < argc; i++)
{
m_cloumn[i] = names[i];
}
}
if (argc > 0)
{
std::vector<std::string>* presult = new std::vector<std::string>;
presult->resize(argc);
for (int i = 0; i < argc; i++)
{
(*presult)[i] = argv[i];
}
m_result.push_back(presult);//为了避免 拷贝问题
}
return 0;
}
int Sqlite::ClearResult()
{
while (m_result.size()>0)
{
std::vector<std::string>* presult = m_result.front();
m_result.pop_front();
if (presult)
{
presult->clear();
delete presult;
}
}
m_cloumn.clear();
return 0;
}
#include "Sqlite.h"
#include
#include
using namespace std;
const char* createtable = "CREATE TABLE TianChen(" \
"ID INT PRIMARY KEY NOT NULL," \
"NAME TEXT NOT NULL );";
const char* inset = "INSERT INTO TianChen (ID,NAME)VALUES(1,\"tianchen1\");";
const char* inset2 = "INSERT INTO TianChen (ID,NAME)VALUES(2,\"tianchen2\");";
const char* droptable = "DROP TABLE TianChen;";
const char* query = "SELECT * FROM TianChen;";
int main()
{
Sqlite sqlite(_T("test.db"));
std::string msg;
int ret = sqlite.Exec(createtable, msg);
if (ret != 0)
{
std::cout << msg << std::endl;
return -1;
}
ret = sqlite.Exec(inset, msg);
if (ret != 0)
{
std::cout << msg << std::endl;
return -1;
}
ret = sqlite.Exec(inset2, msg);
if (ret != 0)
{
std::cout << msg << std::endl;
return -1;
}
std::vector<std::vector<std::string>>result;
std::vector<std::string>cloumns;
//ret = sqlite.Query(query,result,cloumns,msg);
ret = sqlite.QueryContainBlob(query,result,cloumns,msg);
if (ret != 0)
{
std::cout << msg << std::endl;
return -1;
}
for (size_t i = 0; i < result.size(); i++)
{
for (size_t j = 0; j < result[i].size(); j++)
{
std::cout << cloumns[j] << "==" << result[i][j] << std::endl;
}
}
ret = sqlite.Exec(droptable, msg);
if (ret != 0)
{
std::cout << msg << std::endl;
return -1;
}
}