存对象进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协议的。
----------