天天看點

【工具類篇------資料庫】cocos2dx 3.6 sqlite3資料庫的使用

1:首先從官網上把Sqlite3源碼下載下傳下來,放到cocos項目中的Classes下面的某個目錄下,如Classes/database/sqlite3(注意:不要直接放在Classes/sqlite3目錄下)

下面是我自己封裝的讀取sqlite3資料庫記錄的工具類

#pragma once
#ifndef __DBUtil_H__
#define __DBUtil_H__
#include <string>
#include "Csv/sqlite3/sqlite3.h"
#include "DBVersion.h"
#include "Game_Stage.h"
#include "Game_monster_wave.h"
#include "MonsterAnimConfig.h"
using namespace std;

/*
*封裝 sqlite3操作

*@date : 2016.10.13
 @author : cui

*/

class DBUtil
{
public:
	//建立一個db資料庫 db為資料庫的名字
	static void initDB(const char *fileName);

	//判斷表格是否存在
	static bool tableIsExist(string name);

	//tableIsExist的回調函數
	static int isExisted(void * para, int n_column, char ** column_value, char ** column_name);

	//用來建立一個表名為name的表格,建立時會先比對時否有該表的存在如果存在則不建立
	//建立表
	static void createTable(string sql, string name);

	//用來删除一張表名為name的表格,删除時會先比對是否有該表的存在如果不存在則不執行删除操作
	//删除表名
	static void deleteTable(string sql, string name);

	//插入一條資料
	static void insertData(string sql);

	//删除一條資料
	static void deleteData(string sql);

	// 修改一條資料
	static void updateData(string sql);

	// 獲得記錄的條數
	static int getDataCount(string sql);

	//para即傳入的參數  exec中的count參數
	//n_column是這一條記錄有多少個字段(即有多少列)
	// char ** column_value 是個關鍵值,查出來的資料都儲存在這裡,
	//它實際上是個1維數組(不要以為是2維數組),每一個元素都是一個 char * 值,是一個字段内容(用字元串來表示,以/0結尾)
	//char ** column_name 跟 column_value是對應的,表示這個字段的字段名稱

	//關閉打開的資料庫
	static void closeDB();

public:
	//從表中擷取資料

	//讀取一條記錄的資訊
	/*
	*  此方法是查詢方法,相當之重要,pSender最好是個vector
	*/
	//1:stage表
	static void getDataInfoFromGame_stage(string sql, void* para);
	static vector<Game_Stage*> vec_game_stage;

	//2:monsterwave
	static void getDataInfoFromGame_monster_wave(string sql, void* para);
	static vector<Game_monster_wave*> vec_game_monster_wave;

	//3:資料庫版本表
	static void getDataInfoFromDBVersion(string sql, void* para);
	static vector<DBVersion*> vec_DBVersion;

	//4:怪物動畫配置表
	static void getDataInfoFromMonsterAnimConfig(string sql,void *para);
	static vector<MonsterAnimConfig*> vec_monsterAnimConfig;

};
#endif  //__DBUtil_H__
           
#include "DBUtil.h"
#include "cocos2d.h"
#include <vector>
#include "flatbuffers\flatbuffers.h"
#include "Csv/sqlite3/sqlite3.h"
#include "CommonDefine.h"
#include "DBVersion.h"

USING_NS_CC;
using namespace std;
#pragma  execution_character_set("utf-8")

sqlite3 *pDB = nullptr;//資料庫指針
char   *errMsg = nullptr;//錯誤資訊
string sqlstr = "";//SQL指令
int  result = -1;//sqlite3_exec傳回值


vector<Game_Stage*> DBUtil::vec_game_stage = vector<Game_Stage*>();
vector<Game_monster_wave*> DBUtil::vec_game_monster_wave = vector<Game_monster_wave*>();
vector<DBVersion*> DBUtil::vec_DBVersion = vector<DBVersion*>();
vector<MonsterAnimConfig*> DBUtil::vec_monsterAnimConfig = vector<MonsterAnimConfig*>();

//建立資料庫
void DBUtil::initDB(const char *fileName)
{
	//打開一個資料庫,如果該資料庫不存在,則建立一個資料庫檔案
	result = sqlite3_open(fileName, &pDB);
	if (result != SQLITE_OK){
		log("打開資料庫失敗,錯誤碼:%d ,錯誤原因:%s\n", result, errMsg);
		return;
	}
}

//在資料庫中判斷名為name的表是否存在,如果不存在則建立這張表
//@示例語句string sqls = "create table user(id integer,username text,password text)";
void DBUtil::createTable(string sql, string name)
{
	std::string fullDBPath = FileUtils::getInstance()->fullPathForFilename(DB_NAME); //FileUtils::getInstance()->getWritablePath() + DB_NAME;
	DBUtil::initDB(fullDBPath.c_str());
	//如果表不存在則建立表,存在則不進行任何操作
	if (!tableIsExist(name))
	{
		//建立表,設定ID為主鍵,且自動增加
		result = sqlite3_exec(pDB, sql.c_str(), NULL, NULL, &errMsg);
		if (result != SQLITE_OK)
		{
			log("建立表失敗,錯誤碼:%d ,錯誤原因:%s\n", result, errMsg);
			return; 
		}
	}
	DBUtil::closeDB();
}

//判斷表格是否存在
bool DBUtil::tableIsExist(string name)
{
	if (pDB != nullptr)
	{
		//判斷表是否存在
		bool tableIsExisted;
		sqlstr = "select count(type) from sqlite_master where type='table' and name ='" + name + "'";
		result = sqlite3_exec(pDB, sqlstr.c_str(), isExisted, &tableIsExisted, &errMsg);
		return tableIsExisted;
	}
	return false;
}

//tableIsExist的回調函數
int DBUtil::isExisted(void * para, int n_column, char ** column_value, char ** column_name)
{
	bool *isExisted_ = (bool*)para;
	*isExisted_ = (**column_value) != '0';
	return 0;
}

//删除表格
//@示例語句sqlstr="drop table name";
void DBUtil::deleteTable(string sql, string name)
{
	std::string fullDBPath = FileUtils::getInstance()->fullPathForFilename(DB_NAME);//FileUtils::getInstance()->getWritablePath() + DB_NAME;
	DBUtil::initDB(fullDBPath.c_str());
	if (tableIsExist(name))
	{
		result = sqlite3_exec(pDB, sql.c_str(), NULL, NULL, &errMsg);
		if (result != SQLITE_OK)
		{
			log("删除表失敗,錯誤碼:%d ,錯誤原因:%s\n", result, errMsg);
			return;
		}
	}
	DBUtil::closeDB();
}

//插入資料
//@示例語句sqlstr=" insert into MyTable_1( name ) values ( '擎天柱' ) ";
void DBUtil::insertData(string sql){
	std::string fullDBPath = FileUtils::getInstance()->fullPathForFilename(DB_NAME);//FileUtils::getInstance()->getWritablePath() + DB_NAME;
	DBUtil::initDB(fullDBPath.c_str());
	result = sqlite3_exec(pDB, sql.c_str(), NULL, NULL, &errMsg);
	if (result != SQLITE_OK)
	{ 
		log("插入記錄失敗,錯誤碼:%d ,錯誤原因:%s\n", result, errMsg);
	}
	DBUtil::closeDB();
}

//删除資料
//@示例語句sqlstr="delete from MyTable_1 where ID = 2";
void DBUtil::deleteData(string sql)
{
	std::string fullDBPath = FileUtils::getInstance()->fullPathForFilename(DB_NAME);// FileUtils::getInstance()->getWritablePath() + DB_NAME;
	DBUtil::initDB(fullDBPath.c_str());
	result = sqlite3_exec(pDB, sql.c_str(), NULL, NULL, &errMsg);
	if (result != SQLITE_OK)
	{
		log("删除記錄失敗,錯誤碼:%d ,錯誤原因:%s\n", result, errMsg);
	}
	DBUtil::closeDB();
}

//修改資料
//@示例語句        sqlstr="update MyTable_1 set name='威震天' where ID = 3";
void DBUtil::updateData(string sql)
{
	std::string fullDBPath = FileUtils::getInstance()->fullPathForFilename(DB_NAME);//FileUtils::getInstance()->getWritablePath() + DB_NAME;
	DBUtil::initDB(fullDBPath.c_str());
	result = sqlite3_exec(pDB, sql.c_str(), NULL, NULL, &errMsg);
	if (result != SQLITE_OK)
	{
		log("修改資料失敗,錯誤碼:%d ,錯誤原因:%s\n", result, errMsg);
	}
	DBUtil::closeDB();
}

//擷取記錄的條數
//@示例語句string sqlsssss = "select count(*) from user";
//@示例語句  取得表格字段的語句string sqlsssss = "select * from user";
int DBUtil::getDataCount(string sql)
{
	std::string fullDBPath = FileUtils::getInstance()->fullPathForFilename(DB_NAME);//FileUtils::getInstance()->getWritablePath() + DB_NAME;
	DBUtil::initDB(fullDBPath.c_str());
	char **dbResult = nullptr; //是 char ** 類型,兩個*号
	int nRow = 0, nColumn = 0;
	result = sqlite3_get_table(pDB, sql.c_str(), &dbResult, &nRow, &nColumn, &errMsg);
	//int index = nColumn;
	//if (result == SQLITE_OK)
	//{
	//	//查詢成功
	//	for (int i = 0; i < nRow; i++)
	//	{
	//		log("第 %d 條記錄 ", i + 1);
	//		for (int j = 0; j < nColumn; j++)
	//		{
	//			log("key = %s  value = %s ", dbResult[j], dbResult[index]);
	//			++index; // dbResult 的字段值是連續的,從第0索引到第 nColumn - 1索引都是字段名稱,
	//					//從第 nColumn 索引開始,後面都是字段值,它把一個二維的表(傳統的行清單示法)用一個扁平的形式來表示
	//		}//for j end
	//	}//for  i  end

	//}
	sqlite3_free_table(dbResult);
	DBUtil::closeDB();
	return nRow;
}

//擷取一條記錄的資訊 其中的pSend是一個實體類我們以後可以自定義一個繼承了Ref的類來代替他儲存資料庫中取出來的資料
/*
*  這裡最好擴充下,讓  pSend  是一個vector
*/

//table began

void DBUtil::getDataInfoFromGame_stage(string sql, void* para)
{
	std::string fullDBPath = FileUtils::getInstance()->fullPathForFilename(DB_NAME);//FileUtils::getInstance()->getWritablePath() + DB_NAME;
	DBUtil::initDB(fullDBPath.c_str());
	
	//初始化集合
	DBUtil::vec_game_stage.clear();

	char **dbResult = nullptr; //是 char ** 類型,兩個*号
	int nRow = 0, nColumn = 0;
	result = sqlite3_get_table(pDB, sql.c_str(), &dbResult, &nRow, &nColumn, &errMsg);
	int index = nColumn - 1;

	if (nRow != 0)
	{
		if (dbResult != nullptr)
		{
			log("dbResult != nullptr");

			if (result == SQLITE_OK)
			{
				//查詢成功
				while (index <= nRow * nColumn)
				{
					Game_Stage* tower = new Game_Stage();
					//this->setID(0);
					if (dbResult[++index] != NULL)
					{
						tower->setID(atoi(dbResult[index]));
					}
					//this->setStage_id(0);
					if (dbResult[++index] != NULL)
					{
						tower->setStage_id(atoi(dbResult[index]));
					}
					//this->setBase_hp(0);
					if (dbResult[++index] != NULL)
					{
						tower->setBase_hp(atoi(dbResult[index]));
					}
					//setStage_music("");
					if (dbResult[++index] != NULL)
					{
						tower->setStage_music(dbResult[index]);
					}
					//setBoss_music("");
					if (dbResult[++index] != NULL)
					{
						tower->setBoss_music(dbResult[index]);
					}
					vec_game_stage.push_back(tower);
				}//while  end

			}//of result end
		}// if dbResult  end
	}//if nRow > 0  end  存在資料

	//釋放記憶體
	sqlite3_free_table(dbResult);
	DBUtil::closeDB();
}

void DBUtil::getDataInfoFromGame_monster_wave(string sql, void* para)
{
	auto searchPath = FileUtils::getInstance()->getSearchPaths();
	std::string fullDBPath = FileUtils::getInstance()->fullPathForFilename(DB_NAME);//FileUtils::getInstance()->getWritablePath() + DB_NAME;
	DBUtil::initDB(fullDBPath.c_str());

	//初始化集合
	DBUtil::vec_game_monster_wave.clear();

	char **dbResult = nullptr; //是 char ** 類型,兩個*号
	int nRow = 0, nColumn = 0;
	result = sqlite3_get_table(pDB, sql.c_str(), &dbResult, &nRow, &nColumn, &errMsg);
	int index = nColumn - 1;
	if (nRow != 0)
	{
		if (dbResult != nullptr)
		{
			if (result == SQLITE_OK)
			{
				//查詢成功
				while (index <= nRow * nColumn)
				{
					Game_monster_wave* tower = new Game_monster_wave();		
					//this->setID(0);
					if (dbResult[++index] != NULL)
					{
						tower->setID(atoi(dbResult[index]));
					}
					//this->setStage_id(0);
					if (dbResult[++index] != NULL)
					{
						tower->setStage_id(atoi(dbResult[index]));
					}
					//this->setWave(0);
					if (dbResult[++index] != NULL)
					{
						tower->setWave(atoi(dbResult[index]));
					}
					//this->setBoss(0);
					if (dbResult[++index] != NULL)
					{
						tower->setBoss(atoi(dbResult[index]));
					}
					//this->setFormation(0);
					if (dbResult[++index] != NULL)
					{
						tower->setFormation(atoi(dbResult[index]));
					}
					//this->setFormation_configure("");
					if (dbResult[++index] != NULL)
					{
						tower->setFormation_configure(dbResult[index]);
					}
					//this->setFormation_born(0);
					if (dbResult[++index] != NULL)
					{
						tower->setFormation_born(atoi(dbResult[index]));
					}
					//this->setTeam_configure("");
					if (dbResult[++index] != NULL)
					{
						tower->setTeam_configure(dbResult[index]);
					}
					//this->setOrbit(0);
					if (dbResult[++index] != NULL)
					{
						tower->setOrbit(atoi(dbResult[index]));
					}
					//this->setSpeed(0);
					if (dbResult[++index] != NULL)
					{
						tower->setSpeed(atof(dbResult[index]));
					}
					vec_game_monster_wave.push_back(tower);
				}//while  end

			}//of result end
		}// if dbResult  end
	}//if nRow > 0  end  存在資料

	//釋放記憶體
	sqlite3_free_table(dbResult);
	DBUtil::closeDB();
}

void DBUtil::getDataInfoFromDBVersion(string sql, void* para)
{
	std::string fullDBPath = FileUtils::getInstance()->fullPathForFilename(DB_NAME);//FileUtils::getInstance()->getWritablePath() + DB_NAME;
	DBUtil::initDB(fullDBPath.c_str());

	//初始化集合
	DBUtil::vec_DBVersion.clear();

	char **dbResult = nullptr; //是 char ** 類型,兩個*号
	int nRow = 0, nColumn = 0;
	result = sqlite3_get_table(pDB, sql.c_str(), &dbResult, &nRow, &nColumn, &errMsg);
	int index = nColumn - 1;
	if (nRow != 0)
	{
		if (dbResult != nullptr)
		{
			if (result == SQLITE_OK)
			{
				//查詢成功
				while (index <= nRow * nColumn)
				{
					DBVersion* tower = new DBVersion();
					//id
					if (dbResult[++index] != NULL)
					{
						tower->setID(atoi(dbResult[index]));
					}
					//dbversion
					if (dbResult[++index] != NULL)
					{
						tower->setDB_version(dbResult[index]);
					}
					//dbversionName
					if (dbResult[++index] != NULL)
					{
						tower->setDb_versionName(dbResult[index]);
					}
					vec_DBVersion.push_back(tower);
				}//while  end

			}//of result end
		}// if dbResult  end
	}//if nRow > 0  end  存在資料
}

void DBUtil::getDataInfoFromMonsterAnimConfig(string sql, void* para)
{
	std::string fullDBPath = FileUtils::getInstance()->fullPathForFilename(DB_NAME);//FileUtils::getInstance()->getWritablePath() + DB_NAME;
	DBUtil::initDB(fullDBPath.c_str());

	//初始化集合
	DBUtil::vec_DBVersion.clear();

	char **dbResult = nullptr; //是 char ** 類型,兩個*号
	int nRow = 0, nColumn = 0;
	result = sqlite3_get_table(pDB, sql.c_str(), &dbResult, &nRow, &nColumn, &errMsg);
	int index = nColumn - 1;
	if (nRow != 0)
	{
		if (dbResult != nullptr)
		{
			if (result == SQLITE_OK)
			{
				//查詢成功
				while (index <= nRow * nColumn)
				{
					MonsterAnimConfig* tower = new MonsterAnimConfig();
					//id
					if (dbResult[++index] != NULL)
					{
						tower->setID(atoi(dbResult[index]));
					}
					//dbversion
					if (dbResult[++index] != NULL)
					{
						tower->setMonsterNum(dbResult[index]);
					}
					//dbversionName
					if (dbResult[++index] != NULL)
					{
						tower->setActionName(dbResult[index]);
					}
					if (dbResult[++index] != NULL)
					{
						tower->setChances(atoi(dbResult[index]));
					}
					if (dbResult[++index] != NULL)
					{
						tower->setFrame1(dbResult[index]);
					}
					if (dbResult[++index] != NULL)
					{
						tower->setFrame2(dbResult[index]);
					}
					if (dbResult[++index] != NULL)
					{
						tower->setFrame3(dbResult[index]);
					}
					if (dbResult[++index] != NULL)
					{
						tower->setFrame4(dbResult[index]);
					}
					vec_monsterAnimConfig.push_back(tower);
				}//while  end

			}//of result end
		}// if dbResult  end 
	}//if nRow > 0  end  存在資料
}

//table  end


//void DBUtil::saveUsers(Users* users){
//	std::string fullDBPath = FileUtils::getInstance()->getWritablePath() + DB_NAME;
//	DBUtil::initDB(fullDBPath.c_str());
//
//	string sql = "insert into users (username,oneTotalScore,twoTotalScore) values('"+users->getUserName()+"','"+StringUtils::format("%d",users->getOneTotalScore())+"','"+StringUtils::format("%d",users->getTwoTotalScore())+"')";
//	result = sqlite3_exec(pDB, sql.c_str(), NULL, NULL, &errMsg);
//	if (result != SQLITE_OK)
//	{
//		log("插入記錄失敗,錯誤碼:%d ,錯誤原因:%s\n", result, errMsg);
//	}
//
//	DBUtil::closeDB();
//}
//
//void DBUtil::saveUserScore(UserScore* userScore){
//		std::string fullDBPath = FileUtils::getInstance()->getWritablePath() + DB_NAME;
//	DBUtil::initDB(fullDBPath.c_str());
//
//	//成績
//	stringstream score_ss;
//	int score_int = userScore->getScore();
//	score_ss << score_int;
//	//玩家目前等級
//	stringstream  grade_ss;
//	int grade_int = userScore->getGradeStatus();
//	grade_ss << grade_int;
//	//目前關卡數
//	stringstream tollgate_ss;
//	int tollgate_int = userScore->getCurrentTollgate();
//	tollgate_ss << tollgate_int;
//
//	string sql = "insert into userScore (username,score,gradeStatus,model,currentTime,currentTollgate,result) values('"+userScore->getUserName()+"','"+score_ss.str()+"','"+grade_ss.str()+"','"+userScore->getModel()+"','"+userScore->getcurrentTime()+"','"+tollgate_ss.str()+"','"+userScore->getResult()+"')";
//	result = sqlite3_exec(pDB, sql.c_str(), NULL, NULL, &errMsg);
//	if (result != SQLITE_OK)
//	{
//		log("插入記錄失敗,錯誤碼:%d ,錯誤原因:%s\n", result, errMsg);
//	}
//
//	DBUtil::closeDB();
//}

//關閉資料庫
void DBUtil::closeDB()
{
	sqlite3_close(pDB);
}
           

建表語句如下:

//建立資料庫  在res下面建立資料庫,然後把資料庫複制到data下面,之後操作的都是data下的資料庫
	//assets下面的資料庫不可讀和寫 
	std::string  fullDBPath = FileUtils::getInstance()->getWritablePath() + DB_NAME;
	log("=======%s", fullDBPath.c_str());
	DBUtil::initDB(fullDBPath.c_str());

	//1:建立game_stage表
	string game_stage = "create table game_stage(ID integer primary key autoincrement,stage_id integer,base_hp integer, \
												stage_music text,boss_music text)";
	DBUtil::createTable(game_stage, "game_stage");
	//2 建立game_monster_wave表
	string game_monster_wave = "create table game_monster_wave(ID integer primary key autoincrement,stage_id integer,wave integer,boss integer,formation integer, \
							   	formation_configure  text,formation_born integer,team_configure text,orbit integer,speed integer)";
	DBUtil::createTable(game_monster_wave, "game_monster_wave");
	//3 建立資料庫版本表
	string DBVersion = "create table DBVersion(ID integer primary key autoincrement,db_version text,db_versionName text)";
	DBUtil::createTable(DBVersion, "DBVersion");
	
	//4:建立MonsterAnimConfig表
	string MonsterAnimConfig = "create table MonsterAnimConfig(ID integer primary key autoincrement,monsterNum text,actionName text, \
							   							   	chances integer,frame1 text,frame2 text,frame3 text,frame4 text)";
	DBUtil::createTable(MonsterAnimConfig, "MonsterAnimConfig");

	//關閉資料庫
	DBUtil::closeDB();
}
           

參考連結:

http://blog.csdn.net/ym19860303/article/details/8531171

http://www.cnblogs.com/zibuyu/p/3564408.html

http://www.th7.cn/Program/cp/2012/02/05/58097.shtml