{"id":18974674,"url":"https://github.com/pujiaxin33/modeladapter","last_synced_at":"2025-04-19T16:41:00.836Z","repository":{"id":62447988,"uuid":"272191445","full_name":"pujiaxin33/ModelAdapter","owner":"pujiaxin33","description":"Simple JSON Object mapping and SQLite3  written in Swift","archived":false,"fork":false,"pushed_at":"2022-01-27T07:47:26.000Z","size":533,"stargazers_count":26,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-13T03:15:46.470Z","etag":null,"topics":["ios","objectmapper","sqlite","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pujiaxin33.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-14T11:48:45.000Z","updated_at":"2024-07-19T09:43:14.000Z","dependencies_parsed_at":"2022-11-01T23:02:14.832Z","dependency_job_id":null,"html_url":"https://github.com/pujiaxin33/ModelAdapter","commit_stats":null,"previous_names":["pujiaxin33/modeladaptor"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pujiaxin33%2FModelAdapter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pujiaxin33%2FModelAdapter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pujiaxin33%2FModelAdapter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pujiaxin33%2FModelAdapter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pujiaxin33","download_url":"https://codeload.github.com/pujiaxin33/ModelAdapter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249223936,"owners_count":21232833,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ios","objectmapper","sqlite","swift"],"created_at":"2024-11-08T15:15:45.033Z","updated_at":"2025-04-16T09:34:04.135Z","avatar_url":"https://github.com/pujiaxin33.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ModelAdapter\n\nA SQLite ORM for Swift 5.1+ powered by [SQLite.swift](https://github.com/stephencelis/SQLite.swift).\n\n基于SQLite.swift封装的SQLite ORM库，需要Swift 5.1+。减少SQLite.swift库需要的数据库定义、增删改查等样板代码，只需要简单的配置就能完成数据对象对应数据库表的搭建。\n\n# 使用示例\n\n下面是一个简单使用示例，看看`ModelAdapter`如何简化代码！\n\n## Column定义\n\n- 1、数据类型遵从`ModelAdapterModel`协议\n- 2、非可选值属性使用`@Field`进行注解\n- 3、可选值属性使用`@FieldOptional`进行注解\n- 4、在`Field`或`FieldOptional`初始化器填写column相关信息\n\n```Swift\nstruct CustomModel: ModelAdapterModel {\n    @Field(key: \"user_id\", primaryKey: true)\n    var userID: Int = 0\n    @FieldOptional\n    var nickName: String?\n    @FieldOptional(unique: true)\n    var phone: Int?\n    @Field\n    var age: Int = 0\n\n    init() {\n        initFieldExpressions()\n    }\n}\n```\n\n## `ModelAdapterModel`其他配置\n\n- 实现`ModelAdapterModel`协议的指定初始化器，并且在`init`方法调用`initFieldExpressions`方法。\n```Swift\nstruct CustomModel: ModelAdapterModel {\n    init() {\n        initFieldExpressions()\n    }\n}\n```\n\n## 数据库DAO定义\n\n- 自定义`CustomDAO`类，遵从`ModelAdapterDAO`协议\n- 设置关联类型`Entity`为`CustomModel`\n- 实现`ModelAdapterDAO`协议要求的`connection`和`table`属性\n- 整个数据库层的定义就完成了，不需要自己写增删改查的样板代码了。\n\n```Swift\nclass CustomDAO: ModelAdapterDAO {\n    typealias Entity = CustomModel\n    var connection: Connection = try! Connection(\"\\(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])/db.sqlite3\")\n    var table: Table = Table(\"user\")\n\n    required init() {\n    }\n}\n```\n\n## 开始使用\n\n### 通过JSON字典数据创建model。\n引入了[ObjectMapper](https://github.com/tristanhimmelman/ObjectMapper)库完成JSON To Model。\n```Swift\nlet jsonDict = [\"user_id\" : 123, \"nickName\" : \"暴走的鑫鑫\", \"phone\": 123456, \"age\": 33]\nlet model = CustomModel(JSON: jsonDict)!\n```\n\n### 创建dao实例并创建数据库表单\n```Swift\nlet dao = CustomDAO()\ndao.createTable()\n```\n\n### 插入数据\n```Swift\ntry? dao.insert(entity: model)\n```\n\n### 删除数据\n```Swift\ntry? dao.delete(model.$userID.expression == 123)\n```\n\n### 更新数据\n```Swift\nmodel.phone = 654321\ntry? dao.update(entity: model, model.$userID.expression == 123)\n```\n\n### 查询数据\n```Swift\n//查询全部\nlet queryAll = try? dao.queryAll() \n//条件查询\nlet queryOne = try? dao.query(model.$userID.expression == 123)\n```\n\n# 详细说明\n\n## 自定义column key\n\n- 默认是属性名称，比如age属性在数据库的column值就是age\n- 通过Field的key进行自定义，比如nickName属性在数据库的column值就是nick_name\n\n```Swift\n@Field(key: \"nick_name\"))\nvar nickName: String = \"名字\"\n@Field\nvar age: Int = 0\n```\n\n## 自动创建数据库column\n\n当首次建表之后，后续添加的属性，会自动创建数据库column。比如现在新增了height属性，只需要正常配置即可。\n```Swift\n@Field\nvar height: Double = 188\n```\n\n## 存储自定义类型\n\n属性的类型是自定义类型时，需要让自定义类型遵从`SQLiteValueStringExpressible`协议并实现相关方法，就能够存储进数据库。为了方便使用，使用`SQLiteValueStorable`协议，它遵从于`SQLiteValueStringExpressible`协议。\n\n`SQLiteValueStorable`协议就是让自定义类型能够和String互相转换，从而能够存储进数据库。更多详细信息，点击[SQLiteValueExtension](https://github.com/pujiaxin33/SQLiteValueExtension)进行了解。\n\n使用`SQLiteValueStorable`协议时需要导入`import SQLiteValueExtension`。\n\n```Swift\nstruct NestModel: SQLiteValueStorable {\n    var nestName: String?\n    var nestAge: Int = 0\n\n    static func fromStringValue(_ stringValue: String) -\u003e NestModel {\n        return NestModel(JSONString: stringValue) ?? NestModel(JSON: [String : Any]())!\n    }\n    var stringValue: String {\n        return toJSONString() ?? \"\"\n    }\n}\n\nclass CustomModel: ModelAdapterModel {\n    @FieldOptional\n    var nest: NestModel?\n}\n```\n\n## 存储数组、字典\n\n以下基础类型都已经遵从`SQLiteValueStringExpressible`协议。\n- `Int`、\n- `Int64`\n- `Bool`\n- `Double`\n- `Float`\n- `String`\n- `Blob`\n- `Data`\n- `Date`\n\n### 存储数组\n\n只需要`Array.Element`遵从于`SQLiteValueStringExpressible`即可。比如`[NestModel]`、`[Int]`、`[Date]`。\n\n### 存储字典\n\n只需要`Dictionay.key`和`Value`遵从于`SQLiteValueStringExpressible`即可。\n比如`[String: NestModel]`、`[Int : NestModel]`、`[String: [NestModel]]`。\n\n## 自定义存储属性\n\n如果值类型没有遵从`SQLiteValueStringExpressible`，就不能使用@Field。需要遵从`ModelAdapterModelCustomStorage`协议，然后自己处理数据的存储流程。存储数据类型`Set\u003cString\u003e`示例如下：\n```Swift\nclass CustomModel: ModelAdapterModel {\n    var customSet: Set\u003cString\u003e? = nil\n}\n    \nextension CustomModel: ModelAdapterCustomStorage {\n    static let customSetExpression = Expression\u003cString?\u003e(\"custom_set\")\n\n    func createColumn(tableBuilder: TableBuilder) {\n        tableBuilder.column(CustomModel.customSetExpression)\n    }\n    func setters() -\u003e [Setter] {\n        guard let set = customSet else {\n            return []\n        }\n        guard let data = try? JSONSerialization.data(withJSONObject: Array(set), options: []) else {\n            return []\n        }\n        return [CustomModel.customSetExpression \u003c- String(data: data, encoding: .utf8)]\n    }\n    mutating func update(with row: Row) {\n        guard let string = row[CustomModel.customSetExpression] else {\n            return\n        }\n        let data = Data(string.utf8)\n        guard let stringArray = try? JSONSerialization.jsonObject(with: data, options: []) as? [String] else {\n            return\n        }\n        self.customSet = Set(stringArray)\n    }\n}\n```\n\n## DAO层使用\n\n`ModelAdapterDAO`协议默认实现了常用的增删改查方法：\n```Swift\nfunc createTable(ifNotExists: Bool)\nfunc insert(entity: Entity) throws\nfunc insert(entities: [Entity]) throws\nfunc deleteAll() throws\nfunc delete(_ predicate: SQLite.Expression\u003cBool\u003e) throws\nfunc delete(_ predicate: SQLite.Expression\u003cBool?\u003e) throws\nfunc update(entity: Entity, _ predicate: SQLite.Expression\u003cBool\u003e) throws\nfunc update(entity: Entity, _ predicate: SQLite.Expression\u003cBool?\u003e) throws\nfunc query(_ predicate: SQLite.Expression\u003cBool\u003e) throws -\u003e Entity?\nfunc query(_ predicate: SQLite.Expression\u003cBool?\u003e) throws -\u003e Entity?\nfunc queryAll() throws -\u003e [Entity]?\n```\n\n### 自定义数据库操作\n\n```Swift\nclass CustomDAO: ModelAdapterDAO {\n    func customUpdate(entity: Entity) throws {\n        let statement = table.update(entity.$nickName.expression \u003c- \"自定义更新\")\n        try connection.run(statement)\n    }\n}\n```\n\n# 安装\n\n## Cocoapods\n\n```\npod 'ModelAdapter', '~\u003e 0.0.8'\n```\n\n# 要求\n\n- iOS 9+\n- Swift 5.1+\n- Xcode 12+\n\n# 依赖\n\n- `SQLite.swift`\n- `SQLiteValueExtension`\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpujiaxin33%2Fmodeladapter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpujiaxin33%2Fmodeladapter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpujiaxin33%2Fmodeladapter/lists"}