如何在你的cocos2dx中使用sqlite3
2015-11-06 23:50
405 查看
从性能上说,XML方式的存储基本可以满足1 MB以下的存储要求。但在更复杂的情景中,我们可能需要存储多种不同的类,每个类也需要存储不同的对象,此时XML存储的速度就将成为瓶颈。即便分文件存储,管理起来也很麻烦,这个时候可以引入数据库来提升存储效率。
关系数据库是一种经典的数据库,其中的数据被组织成表的形式,具有相同形式的数据存放在同一张表中,表内每一行代表一个数据。在表的基础上,数据库为我们提供增、删、改、查等操作,这些操作通常采用SQL(结构化查询语言)表达。这种格式化、集中的存储再加上结构化的操作语言带来一个非常大的好处:可以进行深度的优化,大大提升存储和操作的效率。
SQLite是移动设备上常用的一个嵌入式数据库,具有开源、轻量等特点,其源代码只有两个".c"文件和两个".h"文件,并且已经包括了充分的注释说明。相比MySQL或者SQL Server这样的专业级数据库,甚至是比起同样轻量级的Access,SQLite的部署都可谓非常简单,只要将这4个文件导入工程中即可,这使得编译之后的SQLite非常小。
SQLite将数据库的数据存储在磁盘的单一文件中,并通过简单的外部接口提供SQL支持。由于其设计之初即是针对小规模数据的操作,在查询优化、高并发读写等方面做了极简化的处理,可以保证不占用系统额外的资源,因此,在大多数的嵌入式开发中,会比专业数据库有更快速、高效的执行效率。
好了,看看如何加入Sqlite3吧,先从官网http://www.sqlite.org/download.html,下载你所想要的版本的sqlite,我这下的是3.8.2的,在解压后,只有4个文件,没有.def或者是什么dll,lib,这个是要自己生成的。
解压后,将这四个文件添加到你的当前工程中,然后进行编译一下就可以了。
好了,先看个如何创建一个表:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
![](https://code.csdn.net/assets/ico_fork.svg)
回调函数的格式如下:
int sqlite_callback(
void* pv, /* 由 sqlite3_exec() 的第四个参数传递而来 */
int argc, /* 表的列数 */
char** argv, /* 指向查询结果的指针数组, 可以由 sqlite3_column_text() 得到 */
char** col /* 指向表头名的指针数组, 可以由 sqlite3_column_name() 得到 */
);
参数格式:
传给sqlite3_exec的回调函数,用来显示查询结果
对每一条查询结果调用一次该回调函数
参数:
pv:由sqlite3_exec传递的初始化参数
argc:表头的列数
col:表头的名字数组指针
argv:表头的数据数组指针
返回值:
1:中断查找
0:继续列举查询到的数据
示例表:
+-----------------------------------+
| id | pic | data(16进制数据) |
|-----------------------------------|
| 1 | a.jpg | 00 00 00 ... |
|-----------------------------------|
| 2 | b.jpg | XX XX XX |
+-----------------------------------+
对第一行数据:
argc=3 即 [0]...[2]
argv[0]="1",argv[1]="a.jpg",argv[2]="00 00 00..."(实际16进制数据,非这里显示的字符串形式)
col[0]="id",col[1]="pic",col[2]="data"
说明:
sqlite3_exec() 的回调函数必须按照此格式, 当然形参的名字任意.
如果某列的数据类型不是char*, 则可以对结果执行相关的转换, 如:用atoi()把结果转换为整数(integer), 如果是二进制数据, 则可以直接强制类型转换, 如:(void*)argv[i].
该回调函数有两种返回值类型.
1.返回零:sqlite3_exec() 将继续执行查询.
2.返回非零:sqlite3_exec()将立即中断查询, 且 sqlite3_exec() 将返回 SQLITE_ABORT.
示例:
int i;
for(i=0; i<argc; i++)
{
printf("%s\t%s\n\n", col[i], argv[i]);
}
例子:
m_pGameDataBase = prepareTableInDB( "MyGame2", "E:\\database\\MyGame");
std::string insert_sql_("insert into MyGame2 values(123, \"aaa\", 26, \"man\")");
insertRecordIntoSqlite(insert_sql_);
readRecord();// read the record
//
int readFromSQLite(void *anyParam, int iColumn, char **pColumnValue, char **pColumnName ) {
int icolumenCount = iColumn;
for(int i = 0; i < icolumenCount; ++i) {
CCLOG("%s: %s \n", pColumnName[i], pColumnValue[i]);
}
return 0;
}
void GameController::readRecord() {
std::string read_sql_("select * from MyGame2");
char *perrMsg = 0;
sqlite3_exec( m_pGameDataBase,
read_sql_.c_str(),
readFromSQLite,
NULL,
&perrMsg);
}
sqlite3* GameController::prepareTableInDB(const char* table, const char* dbFilename) {
sqlite3 *splite2Data = 0;
char *errMsg = 0;
if(SQLITE_OK != sqlite3_open(dbFilename, &splite2Data)) {
CCLOG("Open the Game Data Table falied\n");
return 0;
}
std::string string_sql = "create table if not exists " + std::string(table) + "( id int unsigned auto_increment primary key, name varchar(50), age int, sex varchar(10))";
sqlite3_exec(splite2Data,
string_sql.c_str(),
NULL,
NULL,
&errMsg); // create a table;
if(errMsg != 0) {
CCLOG("Create the Data table failed\n");
sqlite3_close(splite2Data);
return 0;
}
return splite2Data;
}
void GameController::insertRecordIntoSqlite(std::string &r_stringOrder) {
char *perrMsg = 0;
int info = sqlite3_exec( m_pGameDataBase,
r_stringOrder.c_str(),
0,
0,
&perrMsg);
do{
if(perrMsg != 0) { // execute the instruct failed
CCLOG("insert a record into the table failed\n");
CCLOG("reason: %d, Error Message: %s \n", info, perrMsg);
break;
}
} while(0);
sqlite3_close(m_pGameDataBase); //
}
关系数据库是一种经典的数据库,其中的数据被组织成表的形式,具有相同形式的数据存放在同一张表中,表内每一行代表一个数据。在表的基础上,数据库为我们提供增、删、改、查等操作,这些操作通常采用SQL(结构化查询语言)表达。这种格式化、集中的存储再加上结构化的操作语言带来一个非常大的好处:可以进行深度的优化,大大提升存储和操作的效率。
SQLite是移动设备上常用的一个嵌入式数据库,具有开源、轻量等特点,其源代码只有两个".c"文件和两个".h"文件,并且已经包括了充分的注释说明。相比MySQL或者SQL Server这样的专业级数据库,甚至是比起同样轻量级的Access,SQLite的部署都可谓非常简单,只要将这4个文件导入工程中即可,这使得编译之后的SQLite非常小。
SQLite将数据库的数据存储在磁盘的单一文件中,并通过简单的外部接口提供SQL支持。由于其设计之初即是针对小规模数据的操作,在查询优化、高并发读写等方面做了极简化的处理,可以保证不占用系统额外的资源,因此,在大多数的嵌入式开发中,会比专业数据库有更快速、高效的执行效率。
好了,看看如何加入Sqlite3吧,先从官网http://www.sqlite.org/download.html,下载你所想要的版本的sqlite,我这下的是3.8.2的,在解压后,只有4个文件,没有.def或者是什么dll,lib,这个是要自己生成的。
解压后,将这四个文件添加到你的当前工程中,然后进行编译一下就可以了。
好了,先看个如何创建一个表:
[cpp] view
plaincopy
![](https://code.csdn.net/assets/CODE_ico.png)
回调函数的格式如下:
int sqlite_callback(
void* pv, /* 由 sqlite3_exec() 的第四个参数传递而来 */
int argc, /* 表的列数 */
char** argv, /* 指向查询结果的指针数组, 可以由 sqlite3_column_text() 得到 */
char** col /* 指向表头名的指针数组, 可以由 sqlite3_column_name() 得到 */
);
参数格式:
传给sqlite3_exec的回调函数,用来显示查询结果
对每一条查询结果调用一次该回调函数
参数:
pv:由sqlite3_exec传递的初始化参数
argc:表头的列数
col:表头的名字数组指针
argv:表头的数据数组指针
返回值:
1:中断查找
0:继续列举查询到的数据
示例表:
+-----------------------------------+
| id | pic | data(16进制数据) |
|-----------------------------------|
| 1 | a.jpg | 00 00 00 ... |
|-----------------------------------|
| 2 | b.jpg | XX XX XX |
+-----------------------------------+
对第一行数据:
argc=3 即 [0]...[2]
argv[0]="1",argv[1]="a.jpg",argv[2]="00 00 00..."(实际16进制数据,非这里显示的字符串形式)
col[0]="id",col[1]="pic",col[2]="data"
说明:
sqlite3_exec() 的回调函数必须按照此格式, 当然形参的名字任意.
如果某列的数据类型不是char*, 则可以对结果执行相关的转换, 如:用atoi()把结果转换为整数(integer), 如果是二进制数据, 则可以直接强制类型转换, 如:(void*)argv[i].
该回调函数有两种返回值类型.
1.返回零:sqlite3_exec() 将继续执行查询.
2.返回非零:sqlite3_exec()将立即中断查询, 且 sqlite3_exec() 将返回 SQLITE_ABORT.
示例:
int i;
for(i=0; i<argc; i++)
{
printf("%s\t%s\n\n", col[i], argv[i]);
}
例子:
m_pGameDataBase = prepareTableInDB( "MyGame2", "E:\\database\\MyGame");
std::string insert_sql_("insert into MyGame2 values(123, \"aaa\", 26, \"man\")");
insertRecordIntoSqlite(insert_sql_);
readRecord();// read the record
//
int readFromSQLite(void *anyParam, int iColumn, char **pColumnValue, char **pColumnName ) {
int icolumenCount = iColumn;
for(int i = 0; i < icolumenCount; ++i) {
CCLOG("%s: %s \n", pColumnName[i], pColumnValue[i]);
}
return 0;
}
void GameController::readRecord() {
std::string read_sql_("select * from MyGame2");
char *perrMsg = 0;
sqlite3_exec( m_pGameDataBase,
read_sql_.c_str(),
readFromSQLite,
NULL,
&perrMsg);
}
sqlite3* GameController::prepareTableInDB(const char* table, const char* dbFilename) {
sqlite3 *splite2Data = 0;
char *errMsg = 0;
if(SQLITE_OK != sqlite3_open(dbFilename, &splite2Data)) {
CCLOG("Open the Game Data Table falied\n");
return 0;
}
std::string string_sql = "create table if not exists " + std::string(table) + "( id int unsigned auto_increment primary key, name varchar(50), age int, sex varchar(10))";
sqlite3_exec(splite2Data,
string_sql.c_str(),
NULL,
NULL,
&errMsg); // create a table;
if(errMsg != 0) {
CCLOG("Create the Data table failed\n");
sqlite3_close(splite2Data);
return 0;
}
return splite2Data;
}
void GameController::insertRecordIntoSqlite(std::string &r_stringOrder) {
char *perrMsg = 0;
int info = sqlite3_exec( m_pGameDataBase,
r_stringOrder.c_str(),
0,
0,
&perrMsg);
do{
if(perrMsg != 0) { // execute the instruct failed
CCLOG("insert a record into the table failed\n");
CCLOG("reason: %d, Error Message: %s \n", info, perrMsg);
break;
}
} while(0);
sqlite3_close(m_pGameDataBase); //
}
相关文章推荐
- cocos 怎么实现技能状态的cd
- cocos2d-x设计模式发掘之九:委托模式
- cocos2d-x设计模式发掘之八:中介者模式
- Cocosd-x设计模式之七:防御式编程模式
- cocos2d-x设计模式发掘之六:观察者模式
- cocos2d-x设计模式发掘之四:外观模式
- cocos2d-x设计模式发掘之五:防御式编程模式
- cocos-lua基础学习(10)scheduler类学习笔记
- cocos-lua基础学习(八)Layer类学习笔记
- cocos-lua基础学习(七)Scene类学习笔记
- cocos2d-x设计模式发掘之三:管理者模式
- cocos2d-x设计模式发掘之二:二段构建模式
- cocos2d-x设计模式发掘之一:单例模式
- cocos2dx-3.0(33) 中的缓存TextureCache、SPriteFrameCache、AnimationCache
- cocos-lua基础学习(九)spite类学习笔记
- 怎么在 cocos3.8 以及 cocos2.2 里面如何引入XML文件
- cocos游戏开发-环境搭建
- 如何用doxygen生成cocos2d-x文档
- Cocos2d-x游戏开发——Lua语言入门(安装、测试)
- cocos-lua基础学习(四)quick层封装后的目录结构