A SQLite ORM for Swift 5.1+ powered by SQLite.swift.
基于SQLite.swift封装的SQLite ORM库,需要Swift 5.1+。减少SQLite.swift库需要的数据库定义、增删改查等样板代码,只需要简单的配置就能完成数据对象对应数据库表的搭建。
下面是一个简单使用示例,看看ModelAdapter
如何简化代码!
- 1、数据类型遵从
ModelAdapterModel
协议 - 2、非可选值属性使用
@Field
进行注解 - 3、可选值属性使用
@FieldOptional
进行注解 - 4、在
Field
或FieldOptional
初始化器填写column相关信息
struct CustomModel: ModelAdapterModel {
@Field(key: "user_id", primaryKey: true)
var userID: Int = 0
@FieldOptional
var nickName: String?
@FieldOptional(unique: true)
var phone: Int?
@Field
var age: Int = 0
init() {
initFieldExpressions()
}
}
- 实现
ModelAdapterModel
协议的指定初始化器,并且在init
方法调用initFieldExpressions
方法。
struct CustomModel: ModelAdapterModel {
init() {
initFieldExpressions()
}
}
- 自定义
CustomDAO
类,遵从ModelAdapterDAO
协议 - 设置关联类型
Entity
为CustomModel
- 实现
ModelAdapterDAO
协议要求的connection
和table
属性 - 整个数据库层的定义就完成了,不需要自己写增删改查的样板代码了。
class CustomDAO: ModelAdapterDAO {
typealias Entity = CustomModel
var connection: Connection = try! Connection("\(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])/db.sqlite3")
var table: Table = Table("user")
required init() {
}
}
引入了ObjectMapper库完成JSON To Model。
let jsonDict = ["user_id" : 123, "nickName" : "暴走的鑫鑫", "phone": 123456, "age": 33]
let model = CustomModel(JSON: jsonDict)!
let dao = CustomDAO()
dao.createTable()
try? dao.insert(entity: model)
try? dao.delete(model.$userID.expression == 123)
model.phone = 654321
try? dao.update(entity: model, model.$userID.expression == 123)
//查询全部
let queryAll = try? dao.queryAll()
//条件查询
let queryOne = try? dao.query(model.$userID.expression == 123)
- 默认是属性名称,比如age属性在数据库的column值就是age
- 通过Field的key进行自定义,比如nickName属性在数据库的column值就是nick_name
@Field(key: "nick_name"))
var nickName: String = "名字"
@Field
var age: Int = 0
当首次建表之后,后续添加的属性,会自动创建数据库column。比如现在新增了height属性,只需要正常配置即可。
@Field
var height: Double = 188
属性的类型是自定义类型时,需要让自定义类型遵从SQLiteValueStringExpressible
协议并实现相关方法,就能够存储进数据库。为了方便使用,使用SQLiteValueStorable
协议,它遵从于SQLiteValueStringExpressible
协议。
SQLiteValueStorable
协议就是让自定义类型能够和String互相转换,从而能够存储进数据库。更多详细信息,点击SQLiteValueExtension进行了解。
使用SQLiteValueStorable
协议时需要导入import SQLiteValueExtension
。
struct NestModel: SQLiteValueStorable {
var nestName: String?
var nestAge: Int = 0
static func fromStringValue(_ stringValue: String) -> NestModel {
return NestModel(JSONString: stringValue) ?? NestModel(JSON: [String : Any]())!
}
var stringValue: String {
return toJSONString() ?? ""
}
}
class CustomModel: ModelAdapterModel {
@FieldOptional
var nest: NestModel?
}
以下基础类型都已经遵从SQLiteValueStringExpressible
协议。
Int
、Int64
Bool
Double
Float
String
Blob
Data
Date
只需要Array.Element
遵从于SQLiteValueStringExpressible
即可。比如[NestModel]
、[Int]
、[Date]
。
只需要Dictionay.key
和Value
遵从于SQLiteValueStringExpressible
即可。
比如[String: NestModel]
、[Int : NestModel]
、[String: [NestModel]]
。
如果值类型没有遵从SQLiteValueStringExpressible
,就不能使用@Field。需要遵从ModelAdapterModelCustomStorage
协议,然后自己处理数据的存储流程。存储数据类型Set<String>
示例如下:
class CustomModel: ModelAdapterModel {
var customSet: Set<String>? = nil
}
extension CustomModel: ModelAdapterCustomStorage {
static let customSetExpression = Expression<String?>("custom_set")
func createColumn(tableBuilder: TableBuilder) {
tableBuilder.column(CustomModel.customSetExpression)
}
func setters() -> [Setter] {
guard let set = customSet else {
return []
}
guard let data = try? JSONSerialization.data(withJSONObject: Array(set), options: []) else {
return []
}
return [CustomModel.customSetExpression <- String(data: data, encoding: .utf8)]
}
mutating func update(with row: Row) {
guard let string = row[CustomModel.customSetExpression] else {
return
}
let data = Data(string.utf8)
guard let stringArray = try? JSONSerialization.jsonObject(with: data, options: []) as? [String] else {
return
}
self.customSet = Set(stringArray)
}
}
ModelAdapterDAO
协议默认实现了常用的增删改查方法:
func createTable(ifNotExists: Bool)
func insert(entity: Entity) throws
func insert(entities: [Entity]) throws
func deleteAll() throws
func delete(_ predicate: SQLite.Expression<Bool>) throws
func delete(_ predicate: SQLite.Expression<Bool?>) throws
func update(entity: Entity, _ predicate: SQLite.Expression<Bool>) throws
func update(entity: Entity, _ predicate: SQLite.Expression<Bool?>) throws
func query(_ predicate: SQLite.Expression<Bool>) throws -> Entity?
func query(_ predicate: SQLite.Expression<Bool?>) throws -> Entity?
func queryAll() throws -> [Entity]?
class CustomDAO: ModelAdapterDAO {
func customUpdate(entity: Entity) throws {
let statement = table.update(entity.$nickName.expression <- "自定义更新")
try connection.run(statement)
}
}
pod 'ModelAdapter', '~> 0.0.8'
- iOS 9+
- Swift 5.1+
- Xcode 12+
SQLite.swift
SQLiteValueExtension