自做的Cocos2d-x sqlite的帮助操作类DBHelper

近日开发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);
}

相关的注释应该写的很清楚了,示例代码和示例数据库我已打包,如有需要改进的地方,大家可给我留言,我虚心接受。代码链接如下

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值