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

      

iOS中 学会如何对sqlite3 进行封装 (纯手工)的更多相关文章

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

    #waring ---(看官注意) ---使用说明: ①在创建自定义model类之前让该类继承自文件中的Model类, ②为model类选一个NSString属性作为主键:(既,在初始化方法里面将从父 ...

  2. ios中 radioButton和DataPIcker,九宫格封装好使用

    下载地址 http://pan.baidu.com/share/link?shareid=2894506499&uk=923776187 引用这几个文件 radiobutton.封装好单选按钮 ...

  3. ios中xml和html解析(封装)

    下载地址  http://pan.baidu.com/share/link?shareid=2902188921&uk=923776187 GDataXML和TFHpple配置是一样的(配置方 ...

  4. QF——iOS中的数据库操作:SQLite数据库,第三方封装库FMDB,CoreData

    SQLite数据库: SQLite是轻量级的数据库,适合应用在移动设备和小型设备上,它的优点是轻量,可移植性强.但它的缺点是它的API是用C写的,不是面向对象的.整体来说,操作起来比较麻烦.所以,一般 ...

  5. 转载 -- iOS中SDK的简单封装与使用

    一.功能总述 在博客开始的第一部分,我们先来看一下我们最终要实现的效果.下图中所表述的就是我们今天博客中要做的事情,下方的App One和App Two都植入了我们将要封装的LoginSDK, 两个A ...

  6. 数据库sqlite3的使用-ios中引用方法

    一.简单说明 在iOS中使用SQLite3,首先要添加库文件libsqlite3.dylib和导入主头文件. 导入头文件,可以使用库中的函数(是纯C语言的) 二.具体说明 新建一个项目,在项目的主界面 ...

  7. iOS中数据库应用基础

    iOS 数据库入门 一.数据库简介 1.什么是数据库? 数据库(Database) 是按照数据结构来组织,存储和管理数据的仓库 数据库可以分为2大种类 关系型数据库(主流) PC端 Oracle My ...

  8. iOS中的数据持久化方式

    iOS中的数据持久化方式,基本上有以下四种:属性列表.对象归档.SQLite3和Core Data. 1.属性列表 涉及到的主要类:NSUserDefaults,一般 [NSUserDefaults ...

  9. iOS中常用的四种数据持久化技术

    iOS中的数据持久化方式,基本上有以下四种:属性列表 对象归档 SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 [NSUserDefaults st ...

随机推荐

  1. 学习图像算法阶段性总结 (附一键修图Demo)

    今天特别感慨.自己从决定研究图像处理.势必要做出一键修图算法. 经历了,三个多月的书籍积累,三个多月的算法调整以及优化. 人是一种奇怪的动物.当你做不到的时候,你以为做到了.自己会感觉非常爽,非常有成 ...

  2. [Android] AutoCompleteTextView:自己主动完毕输入内容的控件(自己主动补全)

    AutoCompleteTextView是EditText的直接子类,与普通EditText的最大不同就是.在用户输入的过程中,能够列出可供选择的输入项.方便使用者. AutoCompleteText ...

  3. 阿里巴巴2016研发project师笔试题

    问题1: 假设下列的公式成立:78+78=123,则採用的是_______进制表示的. 本题实则考察进制转换.能够设为x进制.可是x进制有一个问题.即我们无法对x进制直接进行加减乘除.故转化为我们常见 ...

  4. Django安装与开发虚拟环境搭建01

    Django是一款基于python的MVT的web开发框架(m表示model,主要用于对数据库层的封装  ,v表示view,用于向用户展示结果,c表示controller,是核心,用于处理请求.获取数 ...

  5. [LeetCode] 动态规划入门题目

    最近接触了动态规划这个厉害的方法,还在慢慢地试着去了解这种思想,因此就在LeetCode上面找了几道比较简单的题目练了练手. 首先,动态规划是什么呢?很多人认为把它称作一种"算法" ...

  6. JDBC开源框架:DBUtils使用入门

    在单元测试过程中,只涉及到数据库的直接操作来验证业务逻辑是否正确的情况,DBUtils非常适合使用.它结构简单,包小,友好处理掉那些jdbc异常,让你更专注于业务代码,而非底层的操作.官网对它的定义: ...

  7. 通信机制-TCP/IP、Http、Socket的区别

    原文转自:http://blog.csdn.net/axing1991/article/details/45149087 网络由下往上分为 物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. ...

  8. 零基础学习webpack打包管理

    这些天在项目之余的时间学习了webpack打包项目的东西,非常荣幸的找到一些大神的文章来学习,死劲嚼了几天,终于略知一二.在以后的工作上还需继续学习,下面我将分享我这几天学到的一点东西,希望能让我一个 ...

  9. Linux中dos2unix批量转换

    有时候遇到多层目录下的文件格式需要转换,dos2unix 没有-r之类的递归指令,所以需要与find还有管道结合. find -type f | xargs dos2unix -o

  10. IT服务(运维)管理实施的几个要点--第二章 人员和组织架构

    子曰"没有合适的人" 在流程化的管理模式下,最容易步入的一个误区是按流程设计一个"理想的"组织架构,然后对应于这个架构对人员进行评估.培养,甚至是更换.我见过很 ...