Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fidetro/FFDB

Repository files navigation

FFDB

DUB GitHub stars
更详细的使用介绍在WiKi

前言

原本已经打算弃坑的OC版FFDB,因为SwiftFFDB的一轮重构之后,决定把OC版的也进行重构,主要是针对sql语句这部分的拼接进行了优化,参考了sqlite3的语法设计,总而言之变得更优雅了,同时,4.x的版本使用的是参数化查询,用来防注入。

1.x的文档请移步 这里

2.x的文档请移步 这里

3.x的文档请移步 这里

正文

为什么会有FFDB?

  1. 直接用FMDB代码并不优雅而且十分繁琐,而且并不能像使用CoreData能面向对象管理;
  2. 在项目中经常会遇到不得不使用数据库去存储数据的情况;
  3. 主流的移动端数据库,用过的只有FMDB,CoreData,CoreData在使用的时候觉得要写太多代码了,后来放弃了,只用FMDB的话,没有使用ORM的方便,所以有了FFDB。

CoreData、Realm和对FMDB封装后的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 selectFromClassWhereFormat:@"where age < ? order by name" values:@[@"5"]];

类相当于一张表,对象即数据,这句话贯穿整个设计的思路

适合在什么地方使用以及优势?

  1. 数据量大,NSUserDefault和plist都不能满足的时候;
  2. 对基础数据库语句不太懂的同学;
  3. 不需要对数据库进行很复杂的操作;
  4. 通过runtime实现,(削除) 不需要接触到sqlite语句 (削除ここまで)(还是要懂一点点的)就能满足增删改查;

怎么使用?如何集成?

CocoaPod这里

pod 'FFDB’,’~>4.x’ pod search FFDB如果没有找到,pod setup之后就ok了

如果不使用CocoaPod,请导入FMDB,并且在target的Linked Frameworks and Libraries导入 libsqlite3.0.tbd

image

同时把目录中的这些文件拉到工程中

image

建立好要创建的类继承FFDataBaseModel,声明属性即可, 如一个Person表里,有人名,年龄字段。

@interface Person : FFDataBaseModel
/** 人名 **/
@property(nonatomic,copy) NSString *name;
/** 年龄 **/
@property(nonatomic,copy) NSString *age;
/** 设置主键字段 **/
@property(nonatomic,copy) NSString *priamryID;
//从4.x后版本,必须重写该方法,指定主键字段
+ (NSString *)primaryKeyColumn
{
 return @"primaryID";
}
//从4.x后版本,如需主键自增,还需要自行设置字段属性
+ (NSDictionary *)columnsType
{
 return @{@"priamryID":@"integer PRIMARY KEY AUTOINCREMENT"};
}
//插入:
Person *person = [[Person alloc]init];//创建对象
person.name = @"Fidetro";//设置属性
[person insertObject];//插入数据
//查询:
//等同于查询Person表中所有的对象
[Person selectFromClassAllObject];
//等同于查询年龄是15和名字叫Fidetro的数据
[Person selectFromClassWhereFormat:@"age = ? and name = ? " values:@[@"15",@"Fidetro"]];
//限制只查询2个并从第2个开始
[TestModel selectFromClassWhereFormat:nil orderBy:@"time desc" limit:@"2" offset:@"2" values:nil];
 
//更新:
NSArray *updatePersonArray = [Person selectFromClassWhereFormat:@" name = ? " values:@[@"Fidetro"]];//先查询到要更新的数据
Person *lastPerson = [updatePersonArray lastObject];
assert([lastPerson.name isEqualToString:@"Fidetro"]);
lastPerson.age = 24;
[lastPerson updateObject];
//删除:
NSArray *deletePersonArray = [Person selectFromClassWhereFormat:@"age = ? and name = ? " values:@[@"24",@"Fidetro"]];//先查询到要删除的数据
Person *deletePerson = [deletePersonArray lastObject];
assert(deletePerson.age == 24);
[deletePerson deleteObject];

补充


1. 所有字段都是默认是TEXT,在后面的版本会增加自定义字段类型这个功能;
2. 所有继承FFDataBaseModel的对象,在插入数据库后,都会自带一个primaryID作为唯一标识,同时这是一个自增的字段;
3. 目前FFDB只是提供了简单的增删改查接口,如果要使用目前接口没办法满足的功能,可以通过以下几个方法进行扩充的操作; 通过获取了这两个,可以自己结合FMDB原有的方法进行操作。
4. 4.x版本数据表模型必须重写+ (NSString *)primaryKeyColumn;方法指定主键字段。

获取FMDatabase对象
[FFDBManager database];
获取类在FMDB对应的表名
[Class tableName];
需要自定义表名,需要在子类重写 + (NSString *)tableName;
+ (NSString *)tableName
{
  return @"CustomTableName";
}


4. 有不需要创建到表的属性的时候,现在通过在子类重写+ (NSArray *)memoryPropertys 可以达到效果

//例子
@interface TestModel : FFDataBaseModel
@property(nonatomic,copy) NSString *name;
/** 这是不需要加到表中的字段 **/
@property(nonatomic,copy) NSString *memory;
@property(nonatomic,copy) NSString *_id;
@property(nonatomic,assign) double time;
@end
+ (NSArray *)memoryPropertys
{
 return @[@"memory"];
}


5. 想修改字段的存储类型可以通过重写 + (NSDictionary *)columnsType 自定义字段的属性,修改字段属性,没有重写的字段都会默认是text类型

+ (NSDictionary *)columnsType
{
 return @{@"time":@"double"};
}


6. 自定义字段名可以重写+ (NSDictionary *)customColumns;

这样表的字段是id建的,而不是_id
 + (NSDictionary *)customColumns
 {
 return @{@"_id":@"id"};
 }


7. 如果你的项目使用的是Swift,建议使用SwiftFFDB

Pod版本更新说明

UML类图

image

About

ORM database,is build on top of FMDB

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

AltStyle によって変換されたページ (->オリジナル) /