iOS中 学会如何对sqlite3 进行封装

it2022-05-09  126

 

#waring ---(看官注意) ---使用说明:  

①在创建自定义model类之前让该类继承自文件中的Model类,

②为model类选一个NSString属性作为主键:(既,在初始化方法里面将从父类Model类

  ID属性等于你所选的NSString属性值即可 (具体可参见.下文  二.3 中)

 

  

 

    

 

一.文件夹结构:

二.文件说明:

    1.NSObject+NSCoding

  该文件是对对象类型进行encoding 以及 decoding操作的方法

    2.DataHandle

     1. 该文件是 sqlite3 单例数据库对Model 对象进行增.删.查.改

 

  

  3.Model文件夹下面的Model 是遵守NSCoding 协议的底层Model

     1. 而Model文件夹下面的TestModel 则是继承自Model 的一种自定义model (也就是我们项目中的自定义的Model),

     2.如此,我们自己项目中的自定义model 只要继承字Model 类就可以了,

     3.但还要在自定义的TestModel中添加以下改动: self.ID属性是从父类Model中继承来的 而Model 的ID属性被设置为数据库的主键, 因此不可以为空,需要将TestModel的一个属性替代ID属性,既作为主键;

三.各个文件的代码示例

 1.NSObject+NSCoding

             .h文件

             

             .m文件

 

#import "NSObject+NSCoding.h"#import <objc/runtime.h>#import <UIKit/UIKit.h>@implementation NSObject (NSCoding)- (NSMutableDictionary *)propertiesForClass:(Class)klass {        NSMutableDictionary *results = [[NSMutableDictionary alloc] init];        unsigned int outCount, i;    //通过运行时获取 该类所有属性列表    objc_property_t *properties = class_copyPropertyList(klass, &outCount);    for(i = 0; i < outCount; i++) {        objc_property_t property = properties[i];                NSString *pname = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];        NSString *pattrs = [NSString stringWithCString:property_getAttributes(property) encoding:NSUTF8StringEncoding];                pattrs = [[pattrs componentsSeparatedByString:@","] objectAtIndex:0];        pattrs = [pattrs substringFromIndex:1];                [results setObject:pattrs forKey:pname];    }    free(properties);        if ([klass superclass] != [NSObject class]) {        [results addEntriesFromDictionary:[self propertiesForClass:[klass superclass]]];    }        return results;}- (NSDictionary *)properties {    return [self propertiesForClass:[self class]];}- (void)autoEncodeWithCoder:(NSCoder *)coder {    NSDictionary *properties = [self properties];    for (NSString *key in properties) {        NSString *type = [properties objectForKey:key];        id value;        unsigned long long ullValue;        BOOL boolValue;        float floatValue;        double doubleValue;        NSInteger intValue;        unsigned long ulValue;        long longValue;        unsigned unsignedValue;        short shortValue;        NSString *className;                NSMethodSignature *signature = [self methodSignatureForSelector:NSSelectorFromString(key)];        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];        [invocation setSelector:NSSelectorFromString(key)];        [invocation setTarget:self];                switch ([type characterAtIndex:0]){            case '@':   // object                if ([[type componentsSeparatedByString:@"\""] count] > 1) {                    className = [[type componentsSeparatedByString:@"\""] objectAtIndex:1];                    Class class = NSClassFromString(className);                    #warning UIImage类型的属性不归档  add by yhy›                    if ([className isEqualToString:@"UIImage"]) {                        //如果属性是UIImage类型的,不进行归档                        break;                    }                    #pragma clang diagnostic push#pragma clang diagnostic ignored "-Warc-performSelector-leaks"                    value = [self performSelector:NSSelectorFromString(key)];#pragma clang diagnostic pop                                        // only decode if the property conforms to NSCoding                    if([class conformsToProtocol:@protocol(NSCoding)]){                        [coder encodeObject:value forKey:key];                    }                }                break;            case 'c':   // bool                [invocation invoke];                [invocation getReturnValue:&boolValue];                [coder encodeObject:[NSNumber numberWithBool:boolValue] forKey:key];                break;            case 'f':   // float                [invocation invoke];                [invocation getReturnValue:&floatValue];                [coder encodeObject:[NSNumber numberWithFloat:floatValue] forKey:key];                break;            case 'd':   // double                [invocation invoke];                [invocation getReturnValue:&doubleValue];                [coder encodeObject:[NSNumber numberWithDouble:doubleValue] forKey:key];                break;            case 'i':   // int                [invocation invoke];                [invocation getReturnValue:&intValue];                [coder encodeObject:[NSNumber numberWithInt:(int)intValue] forKey:key];                break;            case 'L':   // unsigned long                [invocation invoke];                [invocation getReturnValue:&ulValue];                [coder encodeObject:[NSNumber numberWithUnsignedLong:ulValue] forKey:key];                break;            case 'Q':   // unsigned long long                [invocation invoke];                [invocation getReturnValue:&ullValue];                [coder encodeObject:[NSNumber numberWithUnsignedLongLong:ullValue] forKey:key];                break;            case 'l':   // long                [invocation invoke];                [invocation getReturnValue:&longValue];                [coder encodeObject:[NSNumber numberWithLong:longValue] forKey:key];                break;            case 's':   // short                [invocation invoke];                [invocation getReturnValue:&shortValue];                [coder encodeObject:[NSNumber numberWithShort:shortValue] forKey:key];                break;            case 'I':   // unsigned                [invocation invoke];                [invocation getReturnValue:&unsignedValue];                [coder encodeObject:[NSNumber numberWithUnsignedInt:unsignedValue] forKey:key];                break;            default:                break;        }    }}- (void)autoDecode:(NSCoder *)coder {    NSDictionary *properties = [self properties];    for (NSString *key in properties) {        NSString *type = [properties objectForKey:key];        id value;        NSNumber *number;        NSInteger i;        CGFloat f;        BOOL b;        double d;        unsigned long ul;        unsigned long long ull;        long longValue;        unsigned unsignedValue;        short shortValue;                NSString *className;                switch ([type characterAtIndex:0]) {            case '@':   // object                if ([[type componentsSeparatedByString:@"\""] count] > 1) {                    className = [[type componentsSeparatedByString:@"\""] objectAtIndex:1];                    Class class = NSClassFromString(className);                    #warning UIImage类型的属性不归档  add by yhy                    if ([className isEqualToString:@"UIImage"]) {                        //如果属性是UIImage类型的,不进行反归档                        break;                    }                    // only decode if the property conforms to NSCoding                    if ([class conformsToProtocol:@protocol(NSCoding )]){                        value = [coder decodeObjectForKey:key];                        [self setValue:value forKey:key];                    }                }                break;            case 'c':   // bool                number = [coder decodeObjectForKey:key];                b = [number boolValue];                [self setValue:@(b) forKey:key];                break;            case 'f':   // float                number = [coder decodeObjectForKey:key];                f = [number floatValue];                [self setValue:@(f) forKey:key];                break;            case 'd':   // double                number = [coder decodeObjectForKey:key];                d = [number doubleValue];                [self setValue:@(d) forKey:key];                break;            case 'i':   // int                number = [coder decodeObjectForKey:key];                i = [number intValue];                [self setValue:@(i) forKey:key];                break;            case 'L':   // unsigned long                number = [coder decodeObjectForKey:key];                ul = [number unsignedLongValue];                [self setValue:@(ul) forKey:key];                break;            case 'Q':   // unsigned long long                number = [coder decodeObjectForKey:key];                ull = [number unsignedLongLongValue];                [self setValue:@(ull) forKey:key];                break;            case 'l':   // long                number = [coder decodeObjectForKey:key];                longValue = [number longValue];                [self setValue:@(longValue) forKey:key];                break;            case 'I':   // unsigned                number = [coder decodeObjectForKey:key];                unsignedValue = [number unsignedIntValue];                [self setValue:@(unsignedValue) forKey:key];                break;            case 's':   // short                number = [coder decodeObjectForKey:key];                shortValue = [number shortValue];                [self setValue:@(shortValue) forKey:key];                break;            default:                break;        }    }}@end

 

    2.DataHandle文件

      .h文件

    

 

      .m文件

      #import <sqlite3.h>#import "DatabaseHandle.h"#import "Model.h"#define ARCHIVERKEY @"archiver"static DatabaseHandle *dataHandle =nil;@implementation DatabaseHandle+ (DatabaseHandle*)shardInstnce{    @synchronized(self){        if (dataHandle == nil) {            dataHandle = [[DatabaseHandle alloc]init];                    }        return dataHandle;    }}//打开数据库static sqlite3 *db = nil;- (void)openDB{        if (db !=nil) {        return;    }        NSString *filePath = [self useCachesPathSqlite:@"WatchBall.sqlite"];    NSLog(@"db filePath = %@",filePath);        int result = sqlite3_open(filePath.UTF8String, &db);    if (result ==SQLITE_OK) {        NSString *createModelSql = @"CREATE TABLE ModelList(ID TEXT PRIMARY KEY,title TEXT,imageUrl TEXT,data BLOB)";        //执行参数?        sqlite3_exec(db, [createModelSql UTF8String], NULL, NULL, NULL);    }}- (void)closeDB{    int result = sqlite3_close(db);    if (result ==SQLITE_OK) {        db = nil;        NSLog(@"关闭成功");    }}//插入收藏活动- (void)insertNewactivity:(Model *)model{    [self openDB];    static sqlite3_stmt *stmt = nil;    NSString *sql = @"insert into ModelList(ID,title,imageUrl,data) values (?,?,?,?)";    int result = sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, nil);        if (result ==SQLITE_OK) {        sqlite3_bind_text(stmt, 1, [model.ID UTF8String], -1, nil);        sqlite3_bind_text(stmt, 2, [model.title UTF8String], -1, nil);        sqlite3_bind_text(stmt, 3, [model.imageUrl UTF8String], -1, nil);                NSString *archiverKey = [NSString stringWithFormat:@"%@%@",ARCHIVERKEY,model.ID];        NSData *data = [self dataOfArchiverObject:model forKey:archiverKey];        sqlite3_bind_blob(stmt, 4, [data bytes], (int)[data length], nil);                sqlite3_step(stmt);    }    sqlite3_finalize(stmt);}- (void)deleteModelByID:(NSString *)ID{        [self openDB];        NSString *deleteSQL = [NSString stringWithFormat:@"delete from ModelList where ID ='%@'",ID];        char * error =nil;        int result = sqlite3_exec(db, deleteSQL.UTF8String, NULL, NULL, &error);        if (result == SQLITE_OK) {                NSLog(@"删除成功");            }else{                NSLog(@"删除失败 error = %s",error);            }      }- (Model*)selectModelWithID:(NSString *)ID{    [self openDB];        sqlite3_stmt *stmt = nil;        NSString *sql = @"select data from ModelList where ID = ?";        int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);        Model *model = nil;        if (result ==SQLITE_OK) {        sqlite3_bind_text(stmt, 1, [ID UTF8String], -1, NULL);        if (sqlite3_step(stmt) ==SQLITE_ROW) {                                    NSData *data = [NSData dataWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)];                        NSString *archiver = [NSString stringWithFormat:@"%@%@",ARCHIVERKEY,ID];            model = [self unarchiverObject:data forKey:archiver];         }    }    sqlite3_finalize(stmt);    return model;    }- (NSArray*)selectAllModel{    [self openDB];        sqlite3_stmt *stmt = nil;    NSString *sql = @"select ID,data from ModelList";        int result = sqlite3_prepare_v2(db, [sql UTF8String], -1, &stmt, NULL);        NSMutableArray *activityArray = [NSMutableArray array];            if (result == SQLITE_OK) {                while (sqlite3_step(stmt) ==SQLITE_ROW) {            NSString *ID = [NSString stringWithUTF8String:(const char*)sqlite3_column_text(stmt, 0)];            NSData *data = [NSData dataWithBytes:sqlite3_column_blob(stmt, 1) length:sqlite3_column_bytes(stmt, 1)];            NSString *modelKey = [NSString stringWithFormat:@"%@%@",ARCHIVERKEY,ID];                        Model * model = [self unarchiverObject:data forKey:modelKey];            [activityArray addObject:model];            NSLog(@"%@",model);                    }    }    sqlite3_finalize(stmt);        if (activityArray.count ==0) {        return nil;    }    return activityArray;}- (BOOL)isFavoriteModelWithID:(NSString *)ID{        Model *model = [self selectModelWithID:ID];    if (model ==nil) {        NSLog(@"没有收藏该条目");        return NO;            }    NSLog(@"已经收藏");    return YES;    }#pragma ---文件路径处理----文件夹路径处理- (NSString*)useCachesPathSqlite:(NSString*)databaseName{        NSString *caches = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject;        NSString *filePath = [caches stringByAppendingPathComponent:databaseName];    return filePath;}#pragma ---归档处理---- (NSData *)dataOfArchiverObject:(id)object forKey:(NSString*)key{    NSMutableData *data = [NSMutableData data];        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];    [archiver encodeObject:object forKey:key];    [archiver finishEncoding];    return data;    }- (id)unarchiverObject:(NSData*)data forKey:(NSString *)key{    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];        id object = [unarchiver decodeObjectForKey:key];    [unarchiver finishDecoding];        return object;}@end

  3.基类Model

      .h文件

                 

 

  

      .m文件

      

 

转载于:https://www.cnblogs.com/zhouyubo/p/4555754.html


最新回复(0)