在iOS开发中,Core Data框架是一个强大的数据存储解决方案,但有时它的复杂性可能会让开发者感到头疼。为了简化这一过程,一个轻量级的对象封装库应运而生,它旨在使Core Data的使用更加直观和方便。这个库的灵感来自于Java中的Persistence API框架,专为常见的使用场景设计,包括处理Core Data堆栈和基本对象(对象图)的查询,以及可能的对管理对象某些属性的投影使用。
这个库通过使用常见的设计模式:数据访问对象(DAO)和工厂模式,覆盖了Core Data框架的基础功能。它的目标是简化开发者与Core Data框架的交互,使得数据操作更加直观和高效。
要开始使用这个库,首先需要在应用程序代理中设置存储数据文件的路径和存储类型,例如对于SQLite存储类型:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[DAOFactory setStorePath:@"test.sqlite"];
[DAOFactory setStoreType:NSSQLiteStoreType];
// ...
}
文件test.sqlite可以是空的,也可以是位于Xcode资源组中的预填充数据库文件。该文件将在第一次自动复制到应用程序的Documents文件夹中。
DAOFactory用于动态创建RuntimeDAO对象或DAOBase类的派生类:
DAOFactory *factory = [DAOFactory factory];
DAO *dao = [factory createRuntimeDAO:@"EntityName"];
可以通过扩展DAOFactory并实现工厂方法来创建自定义的DAO:
DAOFactory *factory = [DAOFactory factory];
MyCustomDAO *dao = (MyCustomDAO*)[factory newDAO:MyCustomDAO.class];
// ...
[dao release];
DAO类及其协议定义了用于管理对象操作的通用方法。每个DAO仅服务于一种单一的管理对象类型,这意味着它只为这种特定的管理对象类型定义。RuntimeDAO类是一个简单的DAO实现,如果不需要为数据对象操作实现自定义方法,可以使用它。
以下是DAO方法声明的示例:
// 返回所有管理对象的ID
-(NSArray*)findAllId;
// 返回所有管理对象
-(NSArray*)findAll;
// 返回所有管理对象 - 带分页
-(NSArray*)findAll:(NSUInteger)fetchOffset limit:(NSUInteger)limit;
// 返回所有管理对象ID - 带分页
-(NSArray*)findAllId:(CDSearchCriteria*)criteria;
// 根据给定条件返回所有管理对象
-(NSArray*)findAll:(CDSearchCriteria*)criteria;
// 根据给定条件返回所有管理对象 - 带分页
-(NSArray*)findAll:(CDSearchCriteria*)criteria fetchOffset:(NSUInteger)fetchOffset limit:(NSUInteger)limit;
// 返回所有管理对象的数量
-(NSUInteger)count;
// 根据给定条件返回所有管理对象的数量
-(NSUInteger)count:(CDSearchCriteria*)criteria;
// 插入新的管理对象并返回给调用者
-(NSManagedObject*)insertNewObject;
// 删除给定的管理对象
-(void)deleteObject:(NSManagedObject*)object;
// 返回给定ID的管理对象
-(NSManagedObject*)findObjectById:(NSManagedObjectID*)objectID;
// 如果标志为YES,则合并对象与持久存储协调器中可用对象的状态;
// 如果标志为NO,则简单地重新加载对象而不合并(这也会导致其他相关管理对象被释放,因此可以使用此方法来修剪想要在内存中持有的对象图的部分)
- (void)refreshObject:(NSManagedObject *)object mergeChanges:(BOOL)flag;
管理对象查询的基础类是CDSearchCriteria类,它简单地持有'过滤器'、'排序'和'投影'。所有适当的类都包含工厂方法,用于实例化所需的标准对象。
过滤器用作查询结果的限制条件。过滤器由CDFilter类(及其子类)表示。此版本不支持Core Data的所有谓词(例如'beginswith'、'ANY'、'ALL'运算符等)。
CDSearchCriteria *criteria = [CDSearchCriteria criteria];
[criteria addFilter:[CDFilter like:@"stringProperty1" value:@"abc*" caseSensitive:NO]];
[criteria addFilter:[CDFilter isNotNull:@"timeStamp"]];
排序用于对查询结果进行排序。排序由CDOrder类表示,非常简单。
CDSearchCriteria *criteria = [CDSearchCriteria criteria];
[criteria addOrder:[CDOrder ascendingOrder:@"timeStamp"]];
投影用于获取不仅仅是管理对象的整个图,而只是属性或计算值。投影由CDProjection类表示。
CDSearchCriteria *criteria = [CDSearchCriteria criteria];
[criteria addProjection:[CDProjection createWithProperty:@"timeStamp"]];
查询成功后,投影结果值存储在字典中,每个结果行一个数组。投影结果的简单值存储在字典中,键为属性名。函数的投影存储在字典中,复合键的形式如下:
@"function name:property name"
例如:
@"min:property1"
函数用于过滤器或投影中,代表管理对象属性值的某些转换。当前版本中,这些是'min'、'max'、'sum'和'lower'。
CDSearchCriteria *criteria = [CDSearchCriteria criteria];
[criteria addFilter:[CDFilter isNotNull:@"timeStamp"]];
[criteria addProjection:[CDProjection createWithFunction:[CDFunction sum:@"doubleValueProperty" resultType:NSDateAttributeType]]];
DAO协议包含基于给定标准轻松创建NSFetchedResultsController的方法:
CDSearchCriteria *criteria = [CDSearchCriteria criteria];
...
DAO *dao = [[DAOFactory factory] createRuntimeDAO:@"Event"];
NSFetchedResultsController *fetchedResultsController = [dao newFetchedResultsController:criteria sectionNameKeyPath:nil cacheName:@"Root"];