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