存对象进FMDB数据库

2017-05-27  本文已影响66人  水煮杰尼龟

前不久用FMDB存过一点数据,一条属性一条属性的加进去的,会很麻烦。作为小白当然要学无止境,所以就参考参考了。
将对象存进数据库的blob字段,先将对象转换成NSData,对象要遵守NSCoding协议,实现归档解档方法。

如下例子:
.h 中

@interface Person : NSObject<NSCoding>
@property (nonatomic,copy)NSString *name;
@property (nonatomic,assign)NSInteger age;
@end

.m中

@implementation Person
-(void)encodeWithCoder:(NSCoder *)aCoder
{
     unsigned int count=0;
    Ivar *ivars=class_copyIvarList([Person class], &count);
    for (int i=0; i<count; i++) {
        Ivar ivar=ivars[i];
        const char *name=ivar_getName(ivar);
        NSString *key=[NSString stringWithUTF8String:name];
        [aCoder encodeObject:[self valueForKey:key] forKey:key];
    }
    free(ivars);
}
-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
    if (self=[super init]) {
        unsigned int count=0;
        Ivar *ivars=class_copyIvarList([Person class], &count);
        for (int i=0; i<count; i++) {
            Ivar ivar=ivars[i];
            const char *name=ivar_getName(ivar);
            NSString *key=[NSString stringWithUTF8String:name];
            id value=[aDecoder decodeObjectForKey:key];   
            [self setValue:value forKey:key];
        }
        free(ivars);    
    }
    return self;
}

用了一丢丢runtime 如果成员变量不多可以一条条写.

然后就可以去搞FMDB了。

NSString *path=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
NSString *sqlitePath=[path stringByAppendingPathComponent:@"persons.sqlite"];
self.db=[FMDatabase databaseWithPath:sqlitePath];
    if ([self.db open]) {
        NSLog(@"---打开成功");
        //blob是二进制对象
        BOOL isCreatTable=[self.db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_person(id integer PRIMARY KEY, person blob NOT NULL)"];
        if (isCreatTable) {
            NSLog(@"---创建表成功");
            Person *person=[[Person alloc]init];
            person.name=@"哇哈哈";
            person.age=20;
            NSData *data=[NSKeyedArchiver archivedDataWithRootObject:person];
            BOOL success=[self.db executeUpdate:@"INSERT INTO t_person(person) VALUES (?);",data];
            if (success) {
                NSLog(@"插入成功");
            }else
            {
                NSLog(@"插入失败");
            }
            
        }else
        {
            NSLog(@"---创建表失败");
        }
    }else
    {
        NSLog(@"---打开失败");
    }
    [self.db close];

这就存进去了。

那么我肯定想查一下o不ok。所以..

    if ([self.db open]) {
        NSLog(@"--打开成功!");
        FMResultSet *result=[self.db executeQuery:@"SELECT id, person FROM t_person ;"];
        while ([result next]) {
            NSInteger ID = [result intForColumnIndex:0];
            NSData *data=[result objectForColumnName:@"person"];
            Person *person=[NSKeyedUnarchiver unarchiveObjectWithData:data];
            NSLog(@"--hj--%ld %@--%ld",ID,person.name,person.age);
        }
        
    
    }else
    {
        NSLog(@"---打开失败!");
    }
    [self.db close];

我查询结果是ok 的。
后面我又想,如果存一堆模型进去,比如tableview cell的数据模型,尝试着放进数组里,直接存数组。结果表明 也是可以的。这时我就在想是不是放进数组的就能直接存进数据库呢?毕竟我是一个小白(屌大的不要bb我),我存了没遵守协议的Model进数组,再把数组存到数据库,结果就崩咯。所以说还是都要遵守NSCoding协议的。
----------

上一篇下一篇

猜你喜欢

热点阅读