美文网首页
CoreStore实战详解 <一>

CoreStore实战详解 <一>

作者: 七秒记忆的鱼儿 | 来源:发表于2019-10-27 22:35 被阅读0次

最近公司要缓存数据,本来开始想使用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的其他写法,再次都不一一列举

相关文章

网友评论

      本文标题:CoreStore实战详解 <一>

      本文链接:https://www.haomeiwen.com/subject/onppvctx.html