structNoteItem: Codable{ var id = 0 var title = "" var content = "" var timeStamp = 0 init(title: String, content: String, timeStamp: Int) { self.title = title self.content = content self.timeStamp = timeStamp } funcencode(to encoder: Encoder)throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(title, forKey: .title) try container.encode(content, forKey: .content) try container.encode(timeStamp, forKey: .timeStamp) } }
因为要用自增主键,就不能自己设定 id,否则 SQLite 会报错。因此要重写 encode 方法,不对对 id 进行编码。而 decode 方法不覆盖,即使用默认方法,把所有属性全部赋值。
连接数据库
构建一个数据库管理类,叫 DataBaseHandler。首先要连接数据库才能进行使用。
1 2 3 4 5 6 7 8 9 10 11 12 13
classDataBaseHandler{ var db: Connection! funcconnect() { do { db = tryConnection(getFilePath()) } catch { print("连接数据库失败") } } funcgetFilePath() -> String { returnNSHomeDirectory() + "/Documents/db.sqlite3" } }
新建 Table
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
let id = Expression<Int64>("id") let title = Expression<String>("title") let content = Expression<String>("content") let timeStamp = Expression<Int64>("timeStamp") let noteList = Table("NoteList") funccreateTable() { do { try db.run(noteList.create(ifNotExists: true) { t in t.column(id, primaryKey: .autoincrement) t.column(title) t.column(content) t.column(timeStamp) }) } catch { print("建表失败") } }
这里指定只有在 Table 不存在的时候才创建。按照数据模型添加列,并把 id 指定为自增主键以获得更好的查找性能。
删除行
作为一个笔记本应用,当然要支持滑动删除。
1 2 3 4 5 6 7 8
funcdeleteItem(id: Int) { let item = noteList.filter(Int64(id) == self.id) do { try db.run(item.delete()) } catch { print("删除失败") } }
这里先通过 id 查找出元素,再调用 db.run(item.delete()) 就可以了,等价于 SQL 语句 DELETE FROM "NoteList" WHERE ("id" = \(id)) 。
插入行
1 2 3 4 5 6 7 8 9 10
funcinsert(_ item: NoteItem) -> Int { do { try db.run(noteList.insert(item)) returnInt(db.lastInsertRowid) } catch { print(error) print("插入失败") } return0 }
由于 id 是数据库自己生成的,为了让外界能拿到 id 号来进行其他的操作,必须把新插入的 id 号返回。可以用 db.lastInsertRowid 拿到最新插入的 id,但其实 run() 函数也是有返回值的,返回值就是 rowid,也可以直接返回。