在 swift 中设置关系数据库 (sqlite) 的步骤

Steps to setting up relational database (sqlite) in swift

我正在开发一个 iOS 应用程序,我想为其设置一个关系数据库。我读到 SQLite 是一个很好用的数据库。我正在 Swift 制作应用程序。我看过几个教程,但似乎我发现的所有教程都有 DBManager class 或 objective-c 中的库。因此,我需要一个 db class 的包装器。我不太确定包装器如何工作以及如何使用 swift 语法调用 objective-c 方法。

我想知道是否有人可以帮助阐明从创建数据库文件并将其添加到您的 xcode 项目到使用具有 swift 语法的 objective-c 库的整个过程为了对数据库文件运行查询。

此外,仅使用看起来更容易使用的 Core Data 值得吗?

Objective-C 教程或​​多或少仍然相关,但显然不会将 Swift 特定的细节纳入其中(FMDB 目前也没有,正如另一位评论者所推荐的那样) .我最终写了 SQLite.swift 来利用 Swift 的一些更有趣的方面(类型安全和泛型,可选):

https://github.com/stephencelis/SQLite.swift

SQLite.swift 提供编译时 safety/confidence,并消除了对大量错误处理的需要。语句和表达式内置 Swift 正确,因此运行时 SQL 语法错误不太可能。

See the documentation 有关创建数据库文件及其存储位置的更多信息(取决于您的需要):

https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#connecting-to-a-database

就 Core Data 而言,它(就像回答此答案时的大多数 Apple 库一样)没有利用 Swift,但它有丰富的遗产,可能是要走的路,尤其是对于较小的持久对象图。但是,如果你想控制关系数据库,或者如果你计划存储一个经常变化的大型数据集,你可能会对 Core Data(以及你需要获得的特定领域的知识)感到沮丧,

您可以使用 this project 中包含的 sqlite 包装器。它是用 Objective-C 编写的,但可以在 Swift.

中轻松使用

SQL Swift 3 的另一个 SQLite 包装器:http://github.com/groue/GRDB.swift

它提供:

  • 著名的 Objective-C FMDB (https://github.com/ccgus/fmdb)

  • 的用户看起来很熟悉的 API
  • 利用 Swift 标准库的低级 SQLite API。

  • 一个漂亮的 Swift 查询界面,适合 SQL 过敏的开发者

  • 支持 SQLite WAL 模式,并发数据库访问以获得额外的性能

  • 记录 class 包装结果集,吃掉你的自定义 SQL 早餐早餐查询,提供持久性操作和更改跟踪。

  • Swift 类型自由:选择适合您数据的正确 Swift 类型。需要时使用 Int64,或者坚持使用方便的 Int。存储和读取 NSDate 或 NSDateComponents。为离散数据类型声明 Swift 枚举。定义您自己的数据库可转换类型。

  • 数据库迁移

  • 速度:https://github.com/groue/GRDB.swift/wiki/Performance

我自己一步一步地遵循了这个步骤,并且由 techtopia 很好地解释了教程。

http://www.techotopia.com/index.php/Swift_iOS_8_Database_Implementation_using_SQLite

http://www.techotopia.com/index.php/An_Example_SQLite_based_iOS_8_Application_using_Swift_and_FMDB

它使用 FMDB 包装器。

创建数据库并Table

override func viewDidLoad() {
super.viewDidLoad()

let filemgr = NSFileManager.defaultManager()
let dirPaths =
NSSearchPathForDirectoriesInDomains(.DocumentDirectory,
        .UserDomainMask, true)

let docsDir = dirPaths[0] as! String

databasePath = docsDir.stringByAppendingPathComponent(
                "contacts.db")

if !filemgr.fileExistsAtPath(databasePath as String) {

    let contactDB = FMDatabase(path: databasePath as String)

    if contactDB == nil {
        println("Error: \(contactDB.lastErrorMessage())")
    }

    if contactDB.open() {
        let sql_stmt = "CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, ADDRESS TEXT, PHONE TEXT)"
        if !contactDB.executeStatements(sql_stmt) {
            println("Error: \(contactDB.lastErrorMessage())")
        }
        contactDB.close()
    } else {
        println("Error: \(contactDB.lastErrorMessage())")
    }
}
}

上述方法中的代码执行以下任务:

-标识应用程序的文档目录并构造到contacts.db数据库文件的路径。

-创建一个 NSFileManager 实例,随后使用它来检测数据库文件是否已经存在。

-如果该文件尚不存在,则代码通过创建一个使用数据库文件路径初始化的 FMDatabase 实例来创建数据库。如果数据库创建成功,则通过调用新数据库实例的打开方法打开它。

-准备一个SQL语句在数据库中创建联系人table并通过调用数据库实例的FMDB executeStatements方法来执行它。

-关闭数据库。

将数据保存到数据库

@IBAction func saveData(sender: AnyObject) {
let contactDB = FMDatabase(path: databasePath as String)

if contactDB.open() {

    let insertSQL = "INSERT INTO CONTACTS (name, address, phone) VALUES ('\(name.text)', '\(address.text)', '\(phone.text)')"

    let result = contactDB.executeUpdate(insertSQL, 
        withArgumentsInArray: nil)

    if !result {
        status.text = "Failed to add contact"
        println("Error: \(contactDB.lastErrorMessage())")
    } else {
        status.text = "Contact Added"
        name.text = ""
        address.text = ""
        phone.text = ""
    }
} else {
    println("Error: \(contactDB.lastErrorMessage())")
}
}

从数据库中获取数据

@IBAction func findContact(sender: AnyObject) {
let contactDB = FMDatabase(path: databasePath as String)

if contactDB.open() {
    let querySQL = "SELECT address, phone FROM CONTACTS WHERE name = '\(name.text)'"

    let results:FMResultSet? = contactDB.executeQuery(querySQL,
     withArgumentsInArray: nil)

    if results?.next() == true {
        address.text = results?.stringForColumn("address")
        phone.text = results?.stringForColumn("phone")
        status.text = "Record Found"
    } else {
        status.text = "Record not found"
        address.text = ""
        phone.text = ""
    }
    contactDB.close()
} else {
    println("Error: \(contactDB.lastErrorMessage())")
}
}