1.x的文档请移步 这里
- 为什么会有FFDB?
- CoreData、Realm和对FMDB封装后的FFDB对比
- 适合在什么地方使用以及优势
- 怎么使用?如何集成?(请直接戳我)
- 1.x和2.x的版本有什么不同?
- 补充
- Pod版本更新说明
- 直接用FMDB代码并不优雅而且十分繁琐,而且并不能像使用CoreData能面向对象管理;
- 在项目中经常会遇到不得不使用数据库去存储数据的情况;
- 主流的移动端数据库,用过的只有FMDB,CoreData,CoreData在使用的时候觉得要写太多代码了,后来放弃了,只用FMDB的话,没有OOP的感觉,所以有了FFDB。
- 解释下FFDB的名字含义,是因为了纪念可能再也见不到的芳芳,不能一起工作真是太可惜了
下面这部分代码出自于Realm的文档
CoreData插入对象
//Create a new Dog
Dog *newDog = [NSEntityDescription insertNewObjectForEntityForName:@"Dog" inManagedObjectContext:myContext];
newDog.name = @"McGruff";
//Save the new Dog object to disk
NSError *saveError = nil;
[newDog.managedObjectContext save:&saveError];
//Rename the Dog
newDog.name = @"Pluto";
[newDog.managedObjectContext save:&saveError];
Realm插入对象
//Create the dog object
Dog *newDog = [[Dog alloc] init];
newDog.name = @"McGruff";
//Save the new Dog object to disk (Using a block for the transaction)
RLMRealm *defaultRealm = [RLMRealm defaultRealm];
[defaultRealm transactionWithBlock:^{
[defaultRealm addObject:newDog];
}];
//Rename the dog (Using open/close methods for the transaction)
[defaultRealm beginWriteTransaction];
newDog.name = @"Pluto";
[defaultRealm commitWriteTransaction];
FFDB插入对象
Dog *newDog = [[Dog alloc] init];
newDog.name = @"McGruff";
[newDog insertObject];
//重命名狗,更新对象
newDog.name = @"Pluto";
[newDog updateObject];
CoreData查询
NSManagedObjectContext *context = self.managedObjectContext;
//A fetch request to get all dogs younger than 5 years old, in alphabetical order
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Dog" inManagedObjectContext:context];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age < 5"];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = entity;
request.predicate = predicate;
request.sortDescriptors = @[sortDescriptor];
NSError *error;
NSArray *dogs = [moc executeFetchRequest:request error:&error];
Realm查询对象
RLMResults *dogs = [[Dog objectsWhere:@"age < 5"] sortedResultsUsingProperty:@"name" ascending:YES];
FFDB查询对象
NSArray<Dog *> *dogs = [Dog selectFromClassPredicateWithFormat:@"where age < 5 order by name"];
类相当于一张表,对象即数据,这句话贯穿整个设计的思路
- 数据量大,NSUserDefault和plist都不能满足的时候;
- 对基础数据库语句不太懂的同学;
- 不需要对数据库进行很复杂的操作;
- 通过runtime实现,
不需要接触到sqlite语句(还是要懂一点点的)就能满足增删改查;
pod 'FFDB’,’~>2.x’ pod search FFDB如果没有找到,pod setup之后就ok了
如果不使用CocoaPod,请导入FMDB
,并且在target的Linked Frameworks and Libraries导入
libsqlite3.0.tbd
同时把目录中的这些文件拉到工程中
建立好要创建的类继承FFDataBaseModel
,声明属性即可,
如一个Person
表里,有人名,年龄字段。
@interface Person : FFDataBaseModel
/** 人名 **/
@property(nonatomic,copy) NSString *name;
/** 年龄 **/
@property(nonatomic,copy) NSString *age;
插入:
Person *person = [[Person alloc]init];//创建对象
person.name = @"Fidetro";//设置属性
[person insertObject];//插入数据
查询:
[Person selectFromClassAllObject];//等同于查询Person表中所有的对象
[Person selectFromClassPredicateWithFormat:@"where age == '15' and name == 'Fidetro'"]//等同于查询年龄是15和名字叫Fidetro的数据
更新:
NSArray *personArray = [Person selectFromClassPredicateWithFormat:@"where name = 'fidetro' and age = '21'"];//先查询到要更新的数据
Person *person = [personArray lastObject];
person.age = @"24";
[person updateObject];
删除:
NSArray *personArray = [Person selectFromClassPredicateWithFormat:@"where name = 'fidetro' and age = '21'"];//先查询到要更新的数据
Person *person = [personArray lastObject];
[person deleteObject];
发现之前设计的并没有把异步的操作考虑进去,去查了一下FMDB的文档,对于异步的操作有特别的说明,需要用到FMDatabaseQueue
,对此对原有的代码进行了重构,同时引入了两个关键的类FFDBSafeOperation
和FFDBTransaction
,设计如下:
FFDBSafeOperation
负责保证数据库的操作是线程安全的
FFDBTransaction
则是对事务操作的封装,在处理数据量大的时候对比起FFDBSafeOperation
和直接操作FFDataBaseModel
效率都要高很多。
1. 所有字段都是默认是TEXT,在后面的版本会增加自定义字段类型这个功能;
2. 所有继承FFDataBaseModel的对象,在插入数据库后,都会自带一个primaryID作为唯一标识,同时这是一个自增的字段;
3. 目前FFDB只是提供了简单的增删改查接口,如果要使用目前接口没办法满足的功能,可以通过以下几个方法进行扩充的操作;
获取FMDatabase对象
[FFDBManager database];
获取类在FMDB对应的表名
[Class tableName];
需要自定义表名,需要在子类重写 + (NSString *)tableName;
+ (NSString *)tableName
{
return @"CustomTableName";
}
通过获取了这两个,可以自己结合FMDB原有的方法进行操作。
4. FFDB支持与swift 3混编。
1.getTableName方法改名为tableName;
- 为了兼容swift3,将FMDB的依赖改成了
s.dependency "FMDB","~> 2.7.2"
- 在创建
FFDataBaseModel
的子类,如果有不需要创建到表的属性的时候,现在可以通过在子类重写+ (NSArray*)memoryPropertys
方法达到效果
//例子
@interface TestModel : FFDataBaseModel
@property(nonatomic,copy) NSString *name;
/** 这是不需要加到表中的字段 **/
@property(nonatomic,copy) NSString *memory;
@property(nonatomic,assign) double time;
@end
+ (NSArray *)memoryPropertys
{
return @[@"memory"];
}
- 现在也可以通过重写
+ (NSDictionary *)columnsType
自定义字段的属性,修改字段属性,没有重写的字段都会默认是text
类型
//例子
+ (NSDictionary *)columnsType
{
return @{@"time":@"double"};
}
在返回模型的泛型的时候,增加了__kindof
强迫症更新了部分接口的名字,以及文档