使用开源库 MagicalRecord 操作 CoreData
MagicalRecord https://github.com/magicalpanda/MagicalRecord
注意: MagicalRecord 在 ARC 下运作,Core Data 是 ORM 方案,据说带来的麻烦比好处多,且 Core Data 建立的表没有主键,但对于对数据库没有性能要求,进行简单的数据操作完全够用,能简化无数的代码量.
MagicalRecord
In software engineering, the active record pattern is a design pattern found in software that stores its data in relational databases. It was named by Martin Fowler in his book Patterns of Enterprise Application Architecture. The interface to such an object would include functions such as Insert, Update, and Delete, plus properties that correspond more-or-less directly to the columns in the underlying database table.
在软件工程中,对象与数据库中的记录实时映射是一种设计模式,在处理关系型数据库的的软件中多有出现.这种设计模式被记录在 Martin Fowler 的<Patterns of Enterprise Application Architecture> 中.被操作对象的接口应该包含增删改查的方法,基本属性不多不少的刚好与数据库中的一条记录相对应.
Active record is an approach to accessing data in a database. A database table or view is wrapped into a class; thus an object instance is tied to a single row in the table. After creation of an object, a new row is added to the table upon save. Any object loaded gets its information from the database; when an object is updated, the corresponding row in the table is also updated. The wrapper class implements accessor methods or properties for each column in the table or view.
实时映射记录是一种操作数据库的方式,一个数据库的表被封装成一个对象;这个对象中的一个实例会对应着该表中的一条记录.当创建一个对象时,一条记录也被插入到表中并保存起来.任何被加载的对象中的属性信息都从数据库中读取;当一个对象更新时,这个数据库表中对应的记录也会更新.这个被封装的类实现了实时操作的方法,且其属性一一对应于数据库中表的属性.
MagicalRecord was inspired by the ease of Ruby on Rails' Active Record fetching. The goals of this code are:
- Clean up my Core Data related code
- Allow for clear, simple, one-line fetches
- Still allow the modification of the NSFetchRequest when request optimizations are needed
MagicalRecord 灵感来自于简洁的Ruby语言中 Rails' Active Record 查询方式. MagicalRecord 这个开源库的核心思想是:
- 清除 Core Data 相关的代码
- 简洁的清除,简单的一行搜索记录的功能
- 当然允许使用NSFetchRequest,当存在着复杂的搜索条件时
拙劣的翻译请勿见怪,以下是我在最新的 Xcode 5.1 开 ARC 的环境下的使用教程.
1. 将 MagicalRecord 文件夹拖入到工程文件中,引入 CoreData.frame 框架
2. 在 .pch 文件中引入头文件 CoreData+MagicalRecord.h
注:只能在.pch文件中引头文件,否则无法通过编译
3. 创建 Model.xcdatamodeld 文件,并创建一个 Student 的 ENTITIES,最后创建出 Student 类
4. 在 Appdelete.m 文件中写以下代码
以下是增删改查的基本操作,但注意一点,在做任何的数据库操作之前,请先初始化以下,在Appdelete载入时初始化一次即可,否则找不到数据库而崩溃,你懂的.
//设置数据库名字
[MagicalRecord setupCoreDataStackWithStoreNamed:@"Model.sqlite"];
增加
增加一条记录
Student *person = [Student MR_createEntity];
person.name = @"Y.X.";
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
注意:创建了对象后是需要执行存储操作的
查询
查询所有的记录
NSArray *students = [Student MR_findAll];
根据某个属性某个条件查询
NSArray *students = [Student MR_findByAttribute:@"name" withValue:@"Y.X."];
根据排序取得搜索结果
NSArray *students = [Student MR_findAllSortedBy:@"name" ascending:YES];
我不一一列举了,查看一下头文件就知道了.
查询所有记录
+ (NSArray *) MR_findAll;
根据上下文句柄查询所有记录
+ (NSArray *) MR_findAllInContext:(NSManagedObjectContext *)context;
根据某个属性排序查询所有记录
+ (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending;
根据某个属性排序以及上下文操作句柄查询所有记录
+ (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context;
根据某个属性排序用谓词来查询记录
+ (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm;
根据某个属性排序以及上下文操作句柄用谓词来查询记录
+ (NSArray *) MR_findAllSortedBy:(NSString *)sortTerm ascending:(BOOL)ascending withPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context;
根据谓词查询
+ (NSArray *) MR_findAllWithPredicate:(NSPredicate *)searchTerm;
根据谓词以及上下文操作句柄来查询
+ (NSArray *) MR_findAllWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context;
以下都是查询一个对象时的操作,与上面重复,不一一赘述
+ (instancetype) MR_findFirst;
+ (instancetype) MR_findFirstInContext:(NSManagedObjectContext *)context;
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm;
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm inContext:(NSManagedObjectContext *)context;
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending;
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchterm sortedBy:(NSString *)property ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context;
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes;
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm andRetrieveAttributes:(NSArray *)attributes inContext:(NSManagedObjectContext *)context;
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending andRetrieveAttributes:(id)attributes, ...;
+ (instancetype) MR_findFirstWithPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortBy ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context andRetrieveAttributes:(id)attributes, ...;
+ (instancetype) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue;
+ (instancetype) MR_findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context;
+ (instancetype) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending;
+ (instancetype) MR_findFirstOrderedByAttribute:(NSString *)attribute ascending:(BOOL)ascending inContext:(NSManagedObjectContext *)context;
修改
NSArray *students = [Student MR_findByAttribute:@"name" withValue:@"Y.X."];
for (Student *tmp in students) {
tmp.name = @"Jane";
}
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
注意:既然要修改首先得需要找到记录,根据条件匹配找到记录,然后修改,然后保存
删除
NSArray *students = [Student MR_findByAttribute:@"name" withValue:@"Frank"];
for (Student *tmp in students) {
[tmp MR_deleteEntity];
}
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
注意:既然要删除首先得需要找到记录,根据条件匹配找到记录,然后删除,然后保存
心得体会
如果项目中对于操作数据库没有性能要求请使用 CoreData 相关的开源库吧.
CoreData 操作较为复杂, MagicalRecord 有着很多的特性,比如可以根据设置在主线程或者子线程中进行操作,方便快捷,能入榜最佳10大开源库自有其独到的地方,会使用 MagicalRecord 需要具备一定的 CoreData 相关知识,本人也只是现学现用,但深知其可以为开发带来的好处,使用数据库的朋友有着如下的一些选择.
1. SQLite3 C函数形式(本人之前做过干嵌入式开发,即使是这样也不推荐使用面向过程毫无对象概念的SQLite3,有更好的方式为什么不用呢?)
2. FMDB 对SQLite3的封装,有着对象的概念,熟悉SQ语句的朋友可以使用,但还没有做到对象与记录实时对应
3. CoreData 他做到了对象与记录实时对应关系,使用其自身的搜索体系(不用SQ语言),但其基本的操作以及配置让人望而却步
4. MagicalRecord 对 CoreData 官方的用法进行了人性化的封装,用过 CoreData 基本操作再使用 MagicalRecord 会深有体会
5. ObjectiveRecord 也是对 CoreData 的人性化封装,使用更加傻瓜,但傻瓜的代价就是牺牲了一些更强大的功能,在Github上搜索关键字即可
附录:
1.默认的就是在后台存储的,不会阻塞主线程
我在 CoreData+MagicalRecord.h 文件中定义了宏 MR_SHORTHAND ,所以在方法中不需要 MR_ 前缀了
以下为代码(提供block来通知存储成功,异步操作)
以下为打印信息
----------------------------------------------------------------------------------------------------------------------------------------------------
2014-03-13 11:17:43.616 StudyMagicalRecord[26416:60b] +[NSManagedObjectContext(MagicalRecord) MR_contextWithStoreCoordinator:](0x2f4498) -> Created Context UNNAMED
2014-03-13 11:17:43.616 StudyMagicalRecord[26416:60b] +[NSManagedObjectContext(MagicalRecord) MR_setRootSavingContext:](0x2f4498) Set Root Saving Context: <NSManagedObjectContext: 0xe74d910>
2014-03-13 11:17:43.617 StudyMagicalRecord[26416:60b] +[NSManagedObjectContext(MagicalRecord) MR_newMainQueueContext](0x2f4498) Created Main Queue Context: <NSManagedObjectContext: 0xe74e040>
2014-03-13 11:17:43.617 StudyMagicalRecord[26416:60b] +[NSManagedObjectContext(MagicalRecord) MR_setDefaultContext:](0x2f4498) Set Default Context: <NSManagedObjectContext: 0xe74e040>
2014-03-13 11:17:43.618 StudyMagicalRecord[26416:60b] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xe74e040) → Saving <NSManagedObjectContext (0xe74e040): *** DEFAULT ***> on *** MAIN THREAD ***
2014-03-13 11:17:43.618 StudyMagicalRecord[26416:60b] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xe74e040) → Save Parents? 1
2014-03-13 11:17:43.619 StudyMagicalRecord[26416:60b] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xe74e040) → Save Synchronously? 0
2014-03-13 11:17:43.619 StudyMagicalRecord[26416:60b] time
2014-03-13 11:17:43.622 StudyMagicalRecord[26416:60b] -[NSManagedObjectContext(MagicalRecord) MR_contextWillSave:](0xe74e040) Context DEFAULT is about to save. Obtaining permanent IDs for new 1 inserted objects
2014-03-13 11:17:43.623 StudyMagicalRecord[26416:60b] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xe74d910) → Saving <NSManagedObjectContext (0xe74d910): *** BACKGROUND SAVING (ROOT) ***> on *** MAIN THREAD ***
2014-03-13 11:17:43.624 StudyMagicalRecord[26416:60b] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xe74d910) → Save Parents? 1
2014-03-13 11:17:43.624 StudyMagicalRecord[26416:60b] -[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:](0xe74d910) → Save Synchronously? 0
2014-03-13 11:17:43.625 StudyMagicalRecord[26416:1303] -[NSManagedObjectContext(MagicalRecord) MR_contextWillSave:](0xe74d910) Context BACKGROUND SAVING (ROOT) is about to save. Obtaining permanent IDs for new 1 inserted objects
2014-03-13 11:17:43.626 StudyMagicalRecord[26416:1303] __70-[NSManagedObjectContext(MagicalSaves) MR_saveWithOptions:completion:]_block_invoke25(0xe74d910) → Finished saving: <NSManagedObjectContext (0xe74d910): *** BACKGROUND SAVING (ROOT) ***> on *** BACKGROUND THREAD ***
2014-03-13 11:17:43.627 StudyMagicalRecord[26416:60b] YES
----------------------------------------------------------------------------------------------------------------------------------------------------
2.如何关闭 MagicalRecord 提供的打印信息?
修改 MagicalRecord.h 23 行处的值,把 0 改为 1 即可.
使用开源库 MagicalRecord 操作 CoreData的更多相关文章
- 使用开源库MagicalRecord操作CoreData
1. 将 MagicalRecord 文件夹拖入到工程文件中,引入 CoreData.frame 框架 2. 在 .pch 文件中引入头文件 CoreData+MagicalRecord.h 注: ...
- 使用开源库 EasyTimeline 操作定时器 NSTimer
EasyTimeline https://github.com/mmislam101/EasyTimeline Sometimes you need things to happen at speci ...
- Android 使用SwipeActionAdapter开源库实现简单列表的左右滑动操作
我们做listview左右滑动操作时,一般中情况下,都是像QQ那样,左滑弹出操作菜单(删除.编辑),然后选择菜单操作: 这样的效果不可谓不好,算是非常经典. 另外,有少数的APP,尤其是任务管理类的A ...
- iOS 项目中用到的一些开源库和第三方组件
iOS 项目中用到的一些 iOS 开源库和第三方组件 分享一下我目前所在公司 iOS 项目中用到的一些 iOS 开源库和第三方组件, 感谢开源, 减少了我们的劳动力, 节约了我们大量的时间, 让我们有 ...
- GitHub上排名前100的iOS开源库介绍(来自github)
主要对当前 GitHub 排名前 100 的项目做一个简单的简介,方便初学者快速了解到当前 Objective-C 在 GitHub 的情况. 若有任何疑问可通过微博@李锦发联系我 项目名称 项目信息 ...
- 【转】深受开发者喜爱的10大Core Data工具和开源库
http://www.cocoachina.com/ios/20150902/13304.html 在iOS和OSX应用程序中存储和查询数据,Core Data是一个很好的选择.它不仅可以减少内存使用 ...
- ios很好的开源库
Tim9Liu9/TimLiu-iOS 自己总结的iOS.mac开源项目及库,持续更新.. 目录 UI 下拉刷新 模糊效果 AutoLayout 富文本 图表 表相关与Tabbar 隐藏与显示 HUD ...
- GitHub 上排名前 100 的 IOS 开源库简介
主要对当前 GitHub 排名前 100 的项目做一个简单的简介, 方便初学者快速了解到当前 Objective-C 在 GitHub 的情况. 项目名称 项目信息 1. AFNetworking 作 ...
- iOS第三方开源库的吐槽和备忘(转)
原文:http://www.cocoachina.com/industry/20140123/7746.html 做iOS开发总会接触到一些第三方库,这里整理一下,做一些吐槽. 目前比较活跃的社区 ...
随机推荐
- Linux 搭建Hadoop集群错误锦集
一.Hadoop集群配置好后,执行start-dfs.sh后报错,一堆permission denied zf sbin $ ./start-dfs.sh Starting namenodes on ...
- SpringMVC 之 Hello World 入门
1 准备开发环境和运行环境 依赖 jar 包下载,如下图所示: 2 前端控制器的配置 在我们的web.xml中添加如下配置: <!-- The front controller of this ...
- PHP初级篇
PHP初级篇 PHP环境搭建: 企业中常用到的环境是:Linux+Apache+MySQL+PHP 学习环境是:Windows+Apache+MySQL+PHP 工具 Apache 2.4.4 MyS ...
- sql中非存储过程定义参数并使用
DECLARE @dt datetime SET @dt=GETDATE()--1.短日期格式:yyyy-m-d SELECT REPLACE(CONVERT(varchar(10),@dt,120) ...
- synchronized实现可见性
JMM关于synchronized的两条规定: 1)线程解锁前,必须把共享变量的最新值刷新到主内存中 2)线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新获取最新的值 ( ...
- [android] 手机卫士来电显示号码归属地
继续N天前的项目 开启服务监听手机来电,查询数据库,显示归属地 详细内容可以参考这篇博文:http://www.cnblogs.com/taoshihan/p/5331232.html Address ...
- [javaSE] 基本类型(String相关)
字符串是一个特殊的对象 字符串一旦初始化就不可以被改变 获取字符串的长度 调用String对象的length()方法,返回int长度 获取某个索引位置的字符 调用String对象的charAt()方法 ...
- XCode 添加自定义framework运行时出现dyld: Library not loaded的解决方法
XCode添加自定义framework运行时出现dyld: Library not loaded的解决方法 在使用自定义的framework运行时,会出现如下的错误: dyld: Library no ...
- Java并发常见问题
ConcurrentHashMap源码分析,参考:http://blog.csdn.net/do_smile/article/details/46911727 HashMap源码分析,参考:http: ...
- Unix Programming :文件IO
文件描述符常量(unistd.h): STDIN_FILENO STDOUT_FILENO STDERR_FILENO 通常这些常量分别对应于数字0,1,2 文件操作需要头文件 fcntl.h ,一些 ...