有了上面的对象支持,接下来就可以写一个封装类DBHelper.h来实现常用数据访问操作了,如下:
[cpp]
#ifndef DBHelper_h
#define DBHelper_h
#include "SQLiteHelper.h"
//#include <ctime>
#include <iostream>
using namespace std;
using namespace SQLiteWrapper;
namespace SQLiteWrapper {
class DBHelper
{
private:
DBHelper()
{}
virtual ~DBHelper(void)
{}
public:
static DB db;
static DB loadDb()
{
DB database;
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *arr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory/*NSCachesDirectory*/, NSUserDomainMask, YES);
NSString *path = [arr objectAtIndex:0];
path = [path stringByAppendingPathComponent:@"MySqlLitePath"];
// create directory for db if it not exists
NSFileManager *fileManager = [[NSFileManager alloc] init];
BOOL isDirectory = NO;
BOOL exists = [fileManager fileExistsAtPath:path isDirectory:&isDirectory];
if (!exists) {
[fileManager createDirectoryAtPath:path withIntermediateDirectories:NO attributes:nil error:nil];
if (![fileManager fileExistsAtPath:path]) {
[NSException raise:@"FailedToCreateDirectory" format:@"Failed to create a directory for the db at '%@'",path];
}
}
[fileManager release];
// create db object
NSString *dbfilePath = [path stringByAppendingPathComponent:@"Blogs"];
std::string dbpathstr =[dbfilePath UTF8String];
const char *dbpath = dbpathstr.c_str();//"/Users/MySqlLitePath/Blogs";
database.open(dbpath);
[pool release];
}
return database;
}
static bool tableExists(const char* szTable)
{
return db.tableExists(szTable);
}
static int execNoQuery(const char* szSQL)
{
return db.execDML(szSQL);
}
static int execNoQuery(const NSString* szSQL)
{
return db.execDML([szSQL UTF8String].c_str());
}
static Query execQuery(const char* szSQL)
{
return db.execQuery(szSQL);
}
static Query execQuery(const NSString* szSQL)
{
return db.execQuery([szSQL UTF8String].c_str());
}
static Query execScalar(const char* szSQL)
{
return db.execQuery(szSQL);
}
static int execScalar(const NSString* szSQL)
{
return db.execScalar([szSQL UTF8String].c_str());
}
static Table getTable(const char* szSQL)
{
return db.getTable(szSQL);
}
static Table getTable(const NSString* szSQL)
{
return db.getTable([szSQL UTF8String].c_str());
}
static Statement compileStatement(const char* szSQL)
{
return db.compileStatement(szSQL);
}
static Statement compileStatement(const NSString* szSQL)
{
return db.compileStatement([szSQL UTF8String].c_str());
}
static sqlite_int64 lastRowId()
{
return db.lastRowId();
}
static void setBusyTimeout(int nMillisecs)
{
db.setBusyTimeout(nMillisecs);
}
};
}
DB DBHelper::db = DBHelper::loadDb(); //在全局区进行对象初始化操作。
这里要注意的一点就是,在其静态方法loadDb()中,要使用Object-C中的NSAutoreleasePool 对象来"框住"数据库的加载逻辑代码,否则会在下面这一样产生内存泄露:
[cpp]
NSArray *arr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory/*NSCachesDirectory*/, NSUserDomainMask, YES);
下面我们来看如何使用它,上DEMO, 呵呵。
判断当前数据库中是否存在某个TABLE,如存在则删除,之后创建新表:
[cpp]
if(DBHelper::tableExists("emp")){
DBHelper::execNoQuery("drop table emp;");
}
DBHelper::execNoQuery("create table emp(empno int, empname char(20));");
接着向新表中接入数据并返回插入成功的条数,如下:
[cpp]
int nRows = DBHelper::execNoQuery("insert into emp values (7, 'David Beckham');");
cout 《 nRows 《 " rows inserted" 《 endl;
然后进行UPDATE,DELETE操作并返回操作的记录条数:
[cpp]
nRows = DBHelper::execNoQuery("update emp set empname = 'Christiano Ronaldo' where empno = 7;");
cout 《 nRows 《 " rows updated" 《 endl;
nRows = DBHelper::execNoQuery("delete from emp where empno = 7;");
cout 《 nRows 《 " rows deleted" 《 endl;
基于事务属性进行批量操作,以提升性能。