Shark是我觉得目前最好用的SQLite在iOS上的ORM实现。
我的选择
一直以来,iOS上的数据库ORM实现方案都不太合我意。大家主流用到的数据库存储方案大多如下:
- CoreData
- FMDB的衍生类库
- Realm
- NSCoding序列化
- Plist序列化
项目中我用比较多的是CoreData及FMDB,Realm因为是新生数据库引擎、尚在demo/调研阶段,keyarchived以及plist已经不作为主要持久化手段了。
CoreData是苹果在iOS3.0(那些说5.0引入的[微笑])引入的数据持久化框架,虽然支持使用SQLite作为存储后端,但它事实上不是为SQLite而来的;CoreData在设计上就有着存储后端、存储协调、对象上下文、对象模型明确分层的结构,奔着对象图管理(Object-Graph-Management)而非ORM的目标来实现。
Realm是从YC孵化团队推出的自称跨平台(SQLite不跨平台吗?)、高效、使用简单的用于替代CoreData/SQLite的移动数据库引擎,声称比SQLite要快。因为没看到他的评测报告也没了解实现细节(引擎核心还是闭源,据说使用mmap),其他就不说了。但跨线程处理貌似还不如CoreData、模型对象不可跨线程传递就瞬间无爱,暂且略过。
而FMDB实际上仅仅是一个SQLite Wrapper,把C/C++的sqlite接口转换为OC接口而已。所以实际很多人是FMDBxModel(runtime)模型化或者FMDBxMantle直接对接JSON。之前项目中虽然不是基于FMDB但也是基于SQLite+runtime做了property->sqlite.table的映射,这样本已可以满足一般的数据存储需求了。
当初放弃FMDBx系列是状态同步、数据唯一性问题。
先以微信业务举个栗子,个人详情页面修改了备注昵称,我期望的是能以数据驱动的方式驱动通信录、会话列表、聊天页面所涉及个人昵称/备注的UI显示数据的修改,方案要求同一条数据库记录在内存中应该是同一个实例。而以当时的方案来说(包括FMDBx系列以及现在Shark)并没能支持,查询的结果集中每一个都是在内存中新创建的一个实例。结果就是,那时(2014-15)简直是通知乱飞的时代(要不就是一条巨长的delegate调用链、壮观的场面)。
想象一下,一条数据河流主干(我们假设为数据存储控制中心)、若干二/三级支流(业务层),当业务层引起数据变动时,“通知”意味着杂乱穿插水管引流到各个与之有关联的其他支流。而直观来看,数据从支流回到主干、再流动到其他分支是否更合理(也就是,业务层驱动数据/存储层变动,再通知数据管理层及其他业务层)
至于准备放弃CoreData。。是因为旧项目CoreData操作太过繁琐,而多线程处理上经常挖坑埋坑。顺便,CoreData的多线程上,在两三年前大神就指出了Context Stack的方式效率还不如Context Merge;Magical Record似乎没有很好的处理到,最近发现了个比较有趣的第三方库Core Store,但旧项目主Objc就用不上了。
算下来当下已经没几个适合用的了,然后就发现了Shark。除了对象唯一性问题,Shark算是满足我的大部分需求了。
DBAccess: Shark的前世
DBAccess,作者Adrian Herridge,一年前在github开放使用(非开源)。按github上的介绍,DBAccess甚至提供了CoreData数据迁移方法。我竟然一直没听说过这个库。。囧。
目前官网上已声明废弃、替代品为Shark。
Shark
算是因缘巧合,在Info上恰巧看到采访稿
按作者的说法Shark具有与DBAccess近乎一致的操作规范,由于公司高层不同意开源DBAccess暴露业务逻辑,才在DBAccess上进行重构开源的Shark。DBAccess作为一个闭源的framework,根据CocoaPods的统计总下载量达到近9k,采用的app有135个(160720)。也是不错的成绩了。
(Realm已经下载220+w次,App安装接近4w,Star8.2k,不容忽略=.=)
Shark根据目前CocoaPods上面的统计,目前总下载量166,app使用数目35,star为29。
今天简单写了个Shark的demo,使用还是相当简便的!
- 简单测试CURD
- 简单测试多线程:Object传递、存储
- 简单测试事务操作
需要说明(跟进)的问题有:
- 数据表唯一键的问题,组合primary key貌似没找到说明
- 多线程传递Object是安全的!
- 多线程操作Object最终的结果仅依赖于提交的次序
- 嵌套事务存在bug:如果同一个对象在不同transaction中被提交,将会产生多条数据库记录。【待修复】
- 我希望添加的特性:Context维护数据的唯一性,目前实现是每个Object都有内部关联一个context!
demo待补充上传,其他留坑待填。。
Author: Jason
Permalink: http://blog.knpc21.com/undefined/shark-intro-i/
文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。
Comments