参考的是http://blog.youkuaiyun.com/ym19860303/article/details/8531998这篇文章来学习的,同时也有同事的帮忙,写下来的目的是为了防止某一天自己忘记了,可以回来看看。
首先用cocos2dx3.9创建了一个项目newhello,之后导入down下来的sqlite3(不要schell.c)添加完后,如图:
之后新建一个类,将http://blog.youkuaiyun.com/ym19860303/article/details/8531998里.h和.cpp内容copy进来,做一小点修改(根据自己的内容来修改),修改后如何
.h文件如下
#ifndef DBUtil_h
#define DBUtil_h
#include <stdio.h>
#include "sqlite3.h"
//自定义
struct StudentInfo
{
int nID; //id
std::string sName; //姓名
int nAge; //年龄
int nScore; //分数
};
class DBUtil
{
public:
/************************************************************
封装 sqlite3操作
************************************************************/
//用来创建一个db数据库 db为数据库的名字
// 打开数据库
static void initDB(const char *db);
//用来判断表格是否存在
// name:表示表名
static bool tableIsExist(std::string name);
//用来创建一个表名为name的表格,创建时会先匹配时否有该表的存在如果存在则不创建
//创建表
static void createTable(std::string sql,std::string name);
//用来删除一张表名为name的表格,删除时会先匹配是否有该表的存在如果不存在则不执行删除操作
//删除表名
static void deleteTable(std::string sql,std::string name);
//用来向表中插入一条数据
//插入一条数据
static void insertData(std::string sql);
//用来向表中删除一条数据
//删除一条数据
static void deleteData(std::string sql);
//用来向表中修改一条数据
// 修改一条数据
static void updateData(std::string sql);
//获取一个记录的条数
// 获得记录的条数
static int getDataCount(std::string sql);
//读取一条记录的信息
/*
* 此方法是查询方法,相当之重要,pSender最好是个vector
*/
static void getDataInfo(std::string sql,void *pSend);
//关闭打开的数据库
static void closeDB();
static StudentInfo m_studentInfo;
};
#endif /* DBUtil_hpp */
.cpp文件如下:
#include "DBUtil.h"
sqlite3 *pDB = NULL;//数据库指针
char * errMsg = NULL;//错误信息
std::string sqlstr;//SQL指令
int result;//sqlite3_exec返回值
StudentInfo DBUtil::m_studentInfo = {0};
//创建数据库
void DBUtil::initDB(const char *db )
{
//打开一个数据库,如果该数据库不存在,则创建一个数据库文件
result = sqlite3_open(db, &pDB);
if( result != SQLITE_OK )
{
CCLOG( "打开数据库失败,错误码:%d ,错误原因:%s\n" , result, errMsg );
}
}
//tableIsExist的回调函数
int isExistedTable( void * para, int n_column, char ** column_value, char ** column_name )
{
bool *isExisted_=(bool*)para;
*isExisted_=(**column_value)!='0';
return 0;
}
//判断表格是否存在
bool DBUtil::tableIsExist( std::string name )
{
if (pDB!=NULL)
{
//判断表是否存在
bool tableIsExisted;
sqlstr = "select count(type) from sqlite_master where type='table' and name ='"+name+"'";
result =sqlite3_exec(pDB,sqlstr.c_str(),isExistedTable,&tableIsExisted,&errMsg);
return tableIsExisted;
}
return false;
}
//在数据库中判断名为name的表示否存在,如果不存在则创建这张表
//@示例语句string sqls = "create table user(id integer,username text,password text)";
void DBUtil::createTable( std::string sql,std::string name )
{
if (!tableIsExist(name))
{
CCLOG("不存在创建表");
//创建表,设置ID为主键,且自动增加
result = sqlite3_exec(pDB,sql.c_str(),NULL,NULL,&errMsg);
if( result != SQLITE_OK )
{
CCLOG( "创建表失败,错误码:%d ,错误原因:%s\n" , result, errMsg );
}
}
}
//删除表格
//@示例语句sqlstr="drop table name";
void DBUtil::deleteTable( std::string sql,std::string name )
{
if (tableIsExist(name))
{
result = sqlite3_exec(pDB,sql.c_str(),NULL,NULL,&errMsg);
if( result != SQLITE_OK )
{
CCLOG( "创建表失败,错误码:%d ,错误原因:%s\n" , result, errMsg );
}
}
}
//插入数据
//@示例语句sqlss = "insert into stuInfo (id,name,age,score) values (1601,'张三',19,90)"
void DBUtil::insertData( std::string sql )
{
result = sqlite3_exec( pDB, sql.c_str() , NULL, NULL, &errMsg );
if(result != SQLITE_OK )
{
CCLOG( "插入记录失败,错误码:%d ,错误原因:%s\n" , result, errMsg );
}
}
//删除数据
//@示例语句sqlstr="delete from MyTable_1 where ID = 2";
void DBUtil::deleteData( std::string sql )
{
result=sqlite3_exec( pDB, sql.c_str() , NULL, NULL, &errMsg );
if(result != SQLITE_OK )
{
CCLOG( "插入记录失败,错误码:%d ,错误原因:%s\n" , result, errMsg );
}
}
//修改数据
//@示例语句 updateString = "update stuInfo set score = 95;"
void DBUtil::updateData( std::string sql )
{
result = sqlite3_exec( pDB, sql.c_str() , NULL, NULL, &errMsg );
if(result != SQLITE_OK )
{
CCLOG( "插入记录失败,错误码:%d ,错误原因:%s\n" , result, errMsg );
}
}
//getDataCount的回调函数
int loadRecordCount( void * para, int n_column, char ** column_value, char ** column_name )
{
int *count=(int*)para;
*count=n_column;
return 0;
}
//获取记录的条数
//@示例语句string sqlsssss = "select count(*) from user";
//@示例语句 取得表格字段的语句string sqlsssss = "select * from user";
int DBUtil::getDataCount( std::string sql )
{
int count=0;
sqlite3_exec( pDB, sql.c_str() , loadRecordCount, &count, &errMsg );
return count;
}
//getDataInfo的回调函数
int loadRecord( void * para, int n_column, char ** column_value, char ** column_name )
{
CCLOG("n_column:%d",n_column);
/* 根据用户自定义表里面的格式来获取具体的信息 */
StudentInfo studentInfo={};
std::string str = column_value[0];
studentInfo.nID = atoi(str.c_str());
str = column_value[1];
studentInfo.sName = str;
str = column_value[2];
studentInfo.nAge = atoi(str.c_str());
str = column_value[3];
studentInfo.nScore = atoi(str.c_str());
DBUtil::m_studentInfo = studentInfo;
/* 根据表里面的格式来获取具体的信息 */
for (int i=0; i<n_column; i++)
{
std::string str = column_value[i];
printf("%s:%s ",column_name[i],column_value[i]);
}
printf("\n");
return 0;
}
//获取一条记录的信息 其中的pSend是一个实体类我们以后可以自定义一个继承了CCObject的类来代替他保存数据库中取出来的数据
/*
* 这里最好扩展下,让 pSend 是一个vector
*/
void DBUtil::getDataInfo( std::string sql,void* pSend ) //( std::string sql,void *pSend )
{
/* 用户自定义 */
m_studentInfo = *(StudentInfo *)pSend;
CCLOG("id= %d",m_studentInfo.nID);
sqlite3_exec( pDB, sql.c_str() , loadRecord, pSend, &errMsg );
}
//关闭数据库
void DBUtil::closeDB()
{
sqlite3_close(pDB);
}
之后就是如何运用了,来看看HelloWorldScene是怎么写的(头文件别忘记引用#include "DBUtil.h")
.h文件
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
#include "DBUtil.h"
USING_NS_CC;
//struct StudentInfo
//{
// int nID; //id
// std::string sName; //姓名
// int nAge; //年龄
// int nScore; //分数
//};
class HelloWorld : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
void menuCloseCallback(cocos2d::Ref* pSender);
CREATE_FUNC(HelloWorld);
void readTable();
};
#endif // __HELLOWORLD_SCENE_H__
.cpp 文件如何:
#include "HelloWorldScene.h"
Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();
// 'layer' is an autorelease object
auto layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
origin.y + closeItem->getContentSize().height/2));
// create menu, it's an autorelease object
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
label->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y + visibleSize.height - label->getContentSize().height));
this->addChild(label, 1);
auto sprite = Sprite::create("HelloWorld.png");
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
this->addChild(sprite, 0);
readTable();
return true;
}
void HelloWorld::readTable()
{
std::string fullDBPath = FileUtils::getInstance()->getWritablePath() + "save.db";
CCLOG("fullPath : %s",fullDBPath.c_str());
//打开数据库
DBUtil::initDB(fullDBPath.c_str());
//创建表
// std::string createTableSql = "create table zuma (id integer primary key autoincrement,name char(10),age int,score int);"; //创建表,设置ID(此处为integer)为主键primary key,且自动增加autoincrement
std::string createTableSql = "create table stuInfo (id int ,name char(10),age int,score int);";
DBUtil::createTable(createTableSql.c_str(),"stuInfo");
//向表格中插入数据
std::string sqlss = "insert into stuInfo (id,name,age,score) values (1601,'张三',19,90)";
/* 插入一条数据 */
DBUtil::insertData(sqlss);
// 更新
std::string updateString = "update stuInfo set score = 95;";
DBUtil::updateData(updateString);
/* 查询数据 */
std::string selectStr = "select * from stuInfo";
//DBUtil::getDataInfo(selectStr, 0);
StudentInfo studentInfo;
studentInfo.nID = 1601;
DBUtil::getDataInfo(selectStr, &studentInfo);
studentInfo = DBUtil::m_studentInfo;
CCLOG("id = %d",studentInfo.nID);
CCLOG("name = %s",studentInfo.sName.c_str());
CCLOG("age = %d",studentInfo.nAge);
CCLOG("score = %d",studentInfo.nScore);
/* 不能忘记关闭数据库 */
DBUtil::closeDB();
}
void HelloWorld::menuCloseCallback(Ref* pSender)
{
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
之后运行Xcode后,显示打印信息为
<pre name="code" class="cpp">fullPath : /var/mobile/Containers/Data/Application/1F7B08E5-36C1-4C00-B89B-D900EA35A1EC/Documents/save.db
不存在创建表
id= 1601
n_column:4
id:1601 name:张三 age:19 score:95
id = 1601
name = 张三
age = 19
score = 95
2016-01-19 14:44:22.061 newhello-mobile[6059:1366321] cocos2d: surface size: 1136x640