#import "DataBaseHelper.h"
#import <sqlite3.h>
@interface DataBaseHelper (){
sqlite3* sqliteHandle;
}
@property(nonatomic,retain)NSString* dbFileName;//數(shù)據(jù)庫(kù)文件路徑
@end
@implementation DataBaseHelper
+(DataBaseHelper*)sharedDataBaseHelper{
static DataBaseHelper* dbHelper=nil;
if (dbHelper==nil) {
dbHelper=[[DataBaseHelper alloc] init];
}
return dbHelper;
}
//創(chuàng)建數(shù)據(jù)庫(kù)文件存儲(chǔ)的路徑,一般在documents和library/caches
-(void)dbFileNameWithName:(NSString*)fileName{
//將fileName中的空格替換掉
fileName = [fileName stringByReplacingOccurrencesOfString:@" " withString:@""];
//判斷用戶傳遞進(jìn)來(lái)的文件名是否為nil或者為空字符串
if (fileName) {
//判斷文件名是否為空字符串
if (fileName.length == 0) {
//空字符串@""
NSLog(@"數(shù)據(jù)庫(kù)文件無(wú)名稱,當(dāng)程序關(guān)閉的時(shí)候踪栋,數(shù)據(jù)庫(kù)文件也會(huì)銷毀");
}else{
//判斷文件名是否帶后綴名倦青,如果有就直接使用,如果沒(méi)有芜茵,就添加后綴名之后在使用
if (![fileName hasSuffix:@".sqlite"]) {
//如果沒(méi)有后綴名叙量,添加后綴名之后在使用
fileName = [fileName stringByAppendingString:@".sqlite"];
}
}
}else{
//說(shuō)明文件名為nil
NSLog(@"數(shù)據(jù)庫(kù)文件無(wú)名稱,當(dāng)程序關(guān)閉的時(shí)候,數(shù)據(jù)庫(kù)文件也會(huì)銷毀");
fileName=@"";
}
//將文件名稱拼接成有效的文件路徑
NSString* docPath=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
fileName=[docPath stringByAppendingPathComponent:fileName];
//將處理好的文件名賦值給屬性九串,讓其他方法使用
self.dbFileName=fileName;
}
//打開(kāi)或者創(chuàng)建數(shù)據(jù)庫(kù)文件
-(sqlite3*)creatDB{
int result=sqlite3_open(self.dbFileName.UTF8String, &sqliteHandle);
if (result==SQLITE_OK) {
NSLog(@"創(chuàng)建或者打開(kāi)數(shù)據(jù)庫(kù)成功");
return sqliteHandle;
}else{
NSLog(@"創(chuàng)建或者打開(kāi)數(shù)據(jù)庫(kù)失敗----%d",result);
return NULL;
}
}
//無(wú)返回結(jié)果集執(zhí)行的方法
-(BOOL)noQueryWithSql:(NSString*)sql{
//執(zhí)行任何數(shù)據(jù)庫(kù)操作之前绞佩,先打開(kāi)數(shù)據(jù)庫(kù);操作執(zhí)行完畢之后記得關(guān)閉數(shù)據(jù)庫(kù)
sqlite3* sqlite=[self creatDB];
//執(zhí)行sql語(yǔ)句
if (sqlite) {//保證數(shù)據(jù)庫(kù)打開(kāi)成功
int result=sqlite3_exec(sqlite, sql.UTF8String, NULL, NULL, NULL);
//當(dāng)操作有結(jié)果的時(shí)候一定要關(guān)閉數(shù)據(jù)庫(kù)
sqlite3_close(sqlite);
if (result==SQLITE_OK) {
NSLog(@"執(zhí)行非查詢操作成功");
return YES;
}else{
NSLog(@"執(zhí)行非查詢操作失敗-----%d",result);
return NO;
}
}
//說(shuō)明數(shù)據(jù)庫(kù)打開(kāi)失敗
NSLog(@"執(zhí)行查詢操作的時(shí)候猪钮,打開(kāi)數(shù)據(jù)庫(kù)失敗了");
return NO;
}
//通用查詢方法
-(NSArray*)queryWithSql:(NSString*)sql{
//打開(kāi)數(shù)據(jù)庫(kù)
sqlite3* sqlite=[self creatDB];
//創(chuàng)建可變數(shù)組品山,用來(lái)存放所有的記錄
NSMutableArray* resultMArray=[[NSMutableArray alloc] init];
//聲明伴隨指針,用來(lái)存放所有的記錄
sqlite3_stmt* stmt=NULL;
//預(yù)執(zhí)行
int result=sqlite3_prepare(sqlite, sql.UTF8String, -1, &stmt, NULL);
if (result==SQLITE_OK) {
//說(shuō)明sql語(yǔ)句沒(méi)有問(wèn)題
NSLog(@"執(zhí)行查詢操作成功");
//從伴隨指針中取出每一條記錄
while (sqlite3_step(stmt)==SQLITE_ROW) {
//每執(zhí)行一次循環(huán)體烤低,就取出一條記錄
NSMutableDictionary* mDic=[[NSMutableDictionary alloc] init];
//確定改條記錄有幾個(gè)字段
int sumColumn=sqlite3_column_count(stmt);
//for循環(huán)遍歷一條記錄中的所有字段
for (int i=0; i<sumColumn; i++) {
//獲取當(dāng)前列的數(shù)據(jù)類型
int type = sqlite3_column_type(stmt, i);
//獲取字段名
const char * name = sqlite3_column_name(stmt, i);
NSString* key=[NSString stringWithCString:name encoding:NSUTF8StringEncoding];
//取出每一列的值
switch (type) {
case SQLITE_INTEGER:{
//int類型
int value=sqlite3_column_int(stmt, i);
//為字典賦值
[mDic setObject:@(value) forKey:key];
}
break;
case SQLITE_TEXT:{
//字符串類型
const unsigned char* value=sqlite3_column_text(stmt, i);
NSString* valueStr=[NSString stringWithCString:( const char *)value encoding:NSUTF8StringEncoding];
[mDic setObject:valueStr forKey:key];
}
break;
default:
break;
}
}
//一次for循環(huán)結(jié)束肘交,一條記錄才轉(zhuǎn)換為一個(gè)字典
[resultMArray addObject:mDic];
}
}else{
//說(shuō)明sql語(yǔ)句有問(wèn)題
NSLog(@"執(zhí)行查詢操作失敗-----%d",result);
}
//將伴隨指針?biāo)钟械馁Y源釋放掉,關(guān)閉數(shù)據(jù)庫(kù)
sqlite3_finalize(stmt);
sqlite3_close(sqlite);
//while循環(huán)結(jié)束,說(shuō)明所有的記錄都已經(jīng)獲取完整
return resultMArray;
}
@end
以上方法均在.h中聲明即可