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