近日开发cocos2dx用到 sqlite数据库,发现直接用sqlite API的函数,实在有点蛋疼。就做了一个帮助类,使用这个DBHelper类只要引用一下相关的静态函数,参数传入sql语句即可,具体请看下方代码和说明。
老七是自己引用的sqlite3.h和sqlite3.c文件,没有用cocos2dx自带的lib,因为不知为何老报错- -,这样打包apk的时候,一定记得把sqlite3.c也放到mk文件里去。废话到此结束,直接上代码。
注意:打包成so的时候,一定要把代码里的 vector<map<string,string>>,最后边的“>>”中间加一个空格,就是改为"> >",不然编译通不过,这是因为win下默认可以,linux下或者说原生g++不允许。
DBHelper.h 声明如下
#ifndef __DBHelper__
#define __DBHelper__
#include "cocos2d.h"
#include "sqlite3.h"
#include <map>
using namespace std;
USING_NS_CC;
class DBHelper
{
public:
DBHelper(void);
~DBHelper(void);
static sqlite3 *pDB ;//数据库指针
static char * errMsg;//错误信息
//static std::string sqlstr;//SQL指令
static int result;//sqlite3_exec返回值
static std::string constr;
//static std::vector<;
static void OpenDB();//打开数据库
static int excute(string sql);//增删改,将result返回,在业务逻辑里判断数据库是否操作成功
static vector<map<string,string>> GetTable(string sql);//查询数据,如果数据里含有汉字,请vs里,文件-》高级保存选项-》Unicode (utf-8)无签名,65001
static void CloseDB();//关闭数据库
static int GetSingleData(string sql);//得到一行一列的数据返回,用于查询count,和其他聚合函数
};
#endif
DBhelper.cpp
#include "DBHelper.h"
sqlite3* DBHelper:: pDB=NULL ;//数据库指针
char* DBHelper:: errMsg;//错误信息
int DBHelper::result=0;//sqlite3_exec返回值
std::string DBHelper::constr = "";
//抽取数据回调函数
int loadRecord( void * para, int n_column, char ** column_value, char ** column_name );
//取得 条数的回调函数
int loadRecordCount( void * para, int n_column, char ** column_value, char ** column_name );
DBHelper::DBHelper(void)
{
}
DBHelper::~DBHelper(void)
{
}
void DBHelper::OpenDB()
{
if (constr=="")
{
//数据库位置此处是放在debug.win32包下
//此处这种形式没有处理android沙盒传输数据处理,只限win下和mac下,如果需要打包apk,友情给个链接,如下
//http://blog.csdn.net/xujiayin/article/details/9221851
constr = CCFileUtils::sharedFileUtils()->getWritablePath()+"test.db";
}
//CCLog("constr=%s",constr.c_str());
result = sqlite3_open(constr.c_str(), &pDB);
if( result != SQLITE_OK )
CCLog( "读取数据库失败,错误码:%d ,错误原因:%s\n" , result, errMsg );
}
void DBHelper::CloseDB()
{
if (NULL != pDB)
{
sqlite3_close(pDB);
// delete pDB;
pDB=NULL;
}
}
int DBHelper::excute(string sql)
{
OpenDB();
//sqlite3_exec(pDB,sql,NULL,NULL,&errMsg);
result = sqlite3_exec(pDB,sql.c_str(),NULL,NULL,&errMsg);
if( result != SQLITE_OK )
CCLog( "失败,错误码:%d ,错误原因:%s\n" , result, errMsg );
CloseDB();
return result;
}
vector<map<string,string>> DBHelper::GetTable(string sql)
{
OpenDB();
//创建一个victor用于存储所有数据,每行从数据库抽出来的数据都放在一个map<string,string>里
//第一个string是key,存列名,第二个string是值,存数据库取出的相应数据
vector<map<string,string>> vect;
//执行sqlite api接口函数,把vect的指针飞进回调函数loadRecord里去
sqlite3_exec( pDB, sql.c_str() ,loadRecord, &vect, &errMsg );
if( result != SQLITE_OK )
CCLog( "失败,错误码:%d ,错误原因:%s\n" , result, errMsg );
CloseDB();
//恩,经过回调的处理,这个vector已经装满了,我们想要滴数据
return vect;
}
int loadRecord( void * para, int n_column, char ** column_value, char ** column_name )
{
//CCLog("loadRecord");
//声明map啦
map<string,string> hmap ;
for (int i =0;i<n_column;i++)
{
//把数据 以 key-value的方式把数据库里的数据 存进map
hmap.insert(make_pair<string,string>((string)column_name[i],(string)column_value[i]));
}
vector<map<string,string>>* vect =(vector<map<string,string>>*)para;
//添加进vector
vect->push_back(hmap);
//CCLog("count =%d loadRecord",vect->size());
return 0;
}
int DBHelper::GetSingleData(string sql)
{
OpenDB();
int count=0;
sqlite3_exec( pDB, sql.c_str() , loadRecordCount, &count, &errMsg );
CloseDB();
return count;
}
int loadRecordCount( void * para, int n_column, char ** column_value, char ** column_name )
{
int *count=(int*)para;
*count= (int)atof(column_value[0]);
return 0;
}
演示代码
void HelloWorld::TestSql()
{
//测试增删改的函数,需要测试的话,把这部分的注释恢复成代码即可
/*string str ="insert into userinfo(username,gold)values('lucy',786)";
DBHelper::excute(str);
str ="update userinfo set gold=999 where username='lucy'";
DBHelper::excute(str);*/
//测试多条数据查询
vector<map<string,string>> vect= DBHelper::GetTable("select * from userinfo");
//CCLog("count =%d",vect.size());
for (int i =0;i<vect.size();i++)
{
map<string,string> m = vect[i];
map<string, string >::iterator it;
for (it=m.begin();it!=m.end();it++)
{
//使用iterator的形式得到数据
CCLog("%s=%s",it->first.c_str(), it->second.c_str());
}
//直接使用map索引值得到数据
CCLog("map[userName]=%s,map[gold]=%d",m["userName"].c_str(),atoi(m["gold"].c_str()));
}
//测试几条数据的查询
int count_i= DBHelper::GetSingleData("select count(1) from userinfo");
CCLog("count =%d",count_i);
}
相关的注释应该写的很清楚了,示例代码和示例数据库我已打包,如有需要改进的地方,大家可给我留言,我虚心接受。代码链接如下