zoukankan      html  css  js  c++  java
  • iOS中 学会如何对sqlite3 进行封装

     

    #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文件

          

  • 相关阅读:
    WCF进阶01 服务配置
    资源学习备忘 04
    .NET IoC主流框架 01:Castle Windsor Registering components onebyone
    IIS URL重写模块和ASP.NET路由组件比较
    资源学习备忘 03
    开源组件DockPanel Suite使用
    Dockable Window开源组件分享
    WCF进阶02 服务承载
    Prometheus 初探和配置(安装测试)
    TF31003错误的解决办法
  • 原文地址:https://www.cnblogs.com/zhouyubo/p/4555754.html
Copyright © 2011-2022 走看看