CoreStore实战详解 <一>

最近公司要缓存数据,本来开始想使用FMDB的,但是公司项目是swift的,而它是oc的,leader不同意,就推荐使用了CoreStore,它是swift出的框架,最新的已经支持到swift 5.0,它支持的版本有swift 3.2,swift 4.0 ,swift 5.0,文档也是比较全面,但是确实英文的,不提了,我太难了。

本文章,只面向实战,并不对CoreStore里面的思想、模式、代码等做太多的解释。因为我也不懂,还没看。

image.png

我默认你已经会使用cocopods,安装第三方库了。
以及一些CoreData的简单操作
NSPredicate的操作,本文也会设计一些,但是不会很多

1.创建一个CoreStore的数据库

create CoreData.png

剩下的就是创建你需要的表,以及创建里面的字段,再次都不一一列举,如果不会,请右转百度,左转谷歌

2.使用CoreStore连接次数据库

2.1 初始化一个默认的dataStore,会默认创建一个默认的SQLiteStore

try? CoreStoreDefaults.dataStack.addStorageAndWait()

2.2,我们也是可以 自定义库的

 /**
  xcodeModelName: 表示本地CoreData的名称
  bundle:  表示CoreData所在的bundle
*/
let dataStack = DataStack(xcodeModelName: "CoreStore", bundle: Bundle.main, migrationChain: [])
dataStack.addStorage(
/*
  fileName 表示本地保存的sql的名称,默认是Target的名称
  configuration CoreData的组
**/ 
   SQLiteStore(fileName: "CoreStoreDemo.sqlite",configuration: "Default", localStorageOptions: .recreateStoreOnModelMismatch), completion: {_ in })
/// 将创建的stack赋值给全局变量,那样我们就可以在任何地方去使用了,而不用再次创建
 CoreStoreDefaults.dataStack = dataStack

configuration 参数对应的数据

configuration.png

3.添加数据

数据的操作,CoreStore使用的是同个方法

/**
异步执行的方法
asynchronous: 里面去执行添加,更新,删除,查询等数据的操作
completion:是执行的操作,成功或者失败的后续,如果你不想判断成功或者失败,你就使用下面那个方法,此方法的内部也是调用了下面方法
*/
CoreStoreDefaults.dataStack.perform(asynchronous: nil, completion: nil)
CoreStoreDefaults.dataStack.perform(asynchronous: nil, success: nil, failure: nil)
/*
同步执行的操作
synchronous: 里面去执行添加,更新,删除,查询等数据的操作
waitForAllObservers: 是个bool值,默认是`true`,当为`true`的时候,表示会通知所有的监听者发生改变后,再回返回,也造成一定的死锁,当设置为`false`的时候,是不告诉监听着,直接返回,会降低一些死锁的方式
**/
 CoreStoreDefaults.dataStack.perform(synchronous: nil, waitForAllObservers: Bool)
/// 方法一
/**异步执行,可以在里面创建,更新,删除操作**/

 CoreStoreDefaults.dataStack.perform(asynchronous: { transaction in
    let student = transaction.create(Into<Student>())
    student.name = faker.name.name()
    student.score = Int16(faker.number.randomInt())
    student.grade = [Int16(1),Int16(2)].randomElement()!
 }, completion: { _ in })
/// 方法二
/**同步执行,可以在里面创建,更新,删除操作,
waitForAllObservers,默认是true,会通知完所有的监听着,再返回,有可能会造成死锁(监听里面也更新等)。

如果为false,则不会通知监听着,直接返回,减小死锁的概率
         **/
do {
  try CoreStoreDefaults.dataStack.perform(synchronous: { (transaction) in
     let student = transaction.create(Into<Student>())
     student.name = faker.name.name()
     student.score = Int16(faker.number.randomInt())
     student.grade = [Int16(1),Int16(2)].randomElement()!
   }, waitForAllObservers: false)
   } catch let error {
      print("waitForAllObservers:",error.localizedDescription)
  }

4.查询数据

查询数据库,有以下两个方法,同样的使用的方法也是上面介绍的两个方法操作的

/// 查询符合条件的所有数据,返回的是个`Array`
transaction.fetchAll()
/// 查询符合条件的单个数据,返回的是一个单独的对象
transaction.fetchOne()
/// 查询所有的strudent
CoreStoreDefaults.dataStack.perform(asynchronous: { (transaction) in
   let students = try transaction.fetchAll(From<Student>())
   for student in students {
       print("student.name:", student.name!,"student.score:", student.score)
    }
 }, success: { _ in }, failure: { _ in })

/// 查询单个的`Student`
CoreStoreDefaults.dataStack.perform(asynchronous: { (transaction) -> Student? in
    let student = try transaction.fetchOne(From<Student>())
    print("student.name:", student!.name!,"student.score:", student!.score)
    return student
 }) { (result) in
    switch result {
       case .success(let student):
           print("success,student.name:", student!.name!,"student.score:", student!.score)
        case .failure(let error):
            print("completion error :",error.localizedDescription)
       }
}
4.1.条件where语句的查询

CoreStore是封装与CoreData的,所以使用的是NSPredicate来当条件语句查询的
where 基本介绍

  • and&& 且的关系
  • or|| 或的关系
  • not! 非的关系
/// 下面这几种写法都是可以的,其实Where的本质还是封装的NSPredicate
/// 简单介绍一些 %K 表示 key, %@表示value
/// 相当于 name =  Katlynn Dickens
let predicate = NSPredicate(format: "%K = %@", "name", "Katlynn Dickens")
let student = try transaction.fetchOne(From<Student>(), Where<Student>(predicate))
let student = try transaction.fetchOne(From<Student>(), Where<Student>("%K = %@", "name", "Katlynn Dickens"))
let student = try transaction.fetchOne(From<Student>().where(format: "%K = %@", "name", "Katlynn Dickens"))
4.2 排序

排序使用的关键词是orderBy
.descending(\.score) 根据score倒序排序
.ascending(\.score) 根据score正序排序

let students = try transaction.fetchAll(From<Student>().orderBy(.ascending(\.score)))
let students = try transaction.fetchAll(From<Student>().orderBy(.descending(\.score)))

4.3分页查询

分页查询可是使用tweak配合fetchLimit 和 fetchOffset来使用

/// fetchLimit 查询多少条
///  fetchOffset 间隔多少条,开始取值
let students = try transaction.fetchAll(From<Student>().orderBy(.descending(\.score)).tweak {
    $0.fetchLimit = 1
    $0.fetchOffset = 2
 })

4.4 Select的使用

  • 当我们只需要一条数据中某一个属性值的时候,你还在fetchOne来获取数据,拿取值嘛?其实不需要。我们可以使用queryValue配合select即可
  • 当我们需要一些原始属性的时候,我们可以使用queryAttributes配合select来获取原始属性数组
  • select都是可以可以配合whereorderBytweakGroupBy配合使用到,再次都不一一列举了。
/// 当我们只需要一个参数值的时候,可以使用此方法
try CoreStoreDefaults.dataStack.queryValue(From<Student>(), Select<Student,Int16>("score"))
/// 在此方法上面我们还可以使用一些聚合函数
try CoreStoreDefaults.dataStack.queryValue(From<Student>(), Select<Student,Int16>(.count("score")))
/// 获取原始属性,只有name,score连个属性
/// 返回是一个包含符合条件的`字典数组`
try CoreStoreDefaults.dataStack.queryAttributes(From<Student>().select(Select("name", "score")))
//// 同样的再次方法里面我们也可以使用聚合函数
/// 并且使用了聚合函数的别名 as:
try CoreStoreDefaults.dataStack.queryAttributes(From<Student>().select(Select("name", .average("score", as: "scoreSum"))))

聚合函数,注意:我们可以使用as:来个聚合函数别名

  • .average 平均数
  • .sum
  • count 个数
  • maximum 最大值
  • minimum 最小值

注意,以上的orderBy 分页select都是可以使用类似where的其他写法,再次都不一一列举

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,036评论 1 32
  • 概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据。在iOS开发中,...
    Leeson1989阅读 1,837评论 4 1
  • 文/叶听雨 历史上有很多的名人,人们之所以记住了他们的名字,有的是因为写出了一部伟大的著作,譬如阿加莎·克里斯蒂,...
    叶听雨阅读 770评论 42 37
  • 一口气看完美国电视连续剧“越狱”,意犹未尽……我从2005年开始接触这一连续剧至今,不经不觉已经有12个...
    D032大灰狼_佛山阅读 312评论 0 8
  • 晚班前台,真是忙碌的一天。 1 早班交接工作,盘点售卖区数量 2 接待来店会员, 期间整理了快递,收货入库。 3 ...
    童桦_aa77阅读 190评论 0 0