使用多线程读取FMDB数据库

时间:2016-11-18 07:07:12

标签: ios swift fmdb

我在iOS中使用FMDB数据库库用于sqlite。如何在FMDB中同时执行多个读取操作。目前我正在使用FMDB数据库队列。

3 个答案:

答案 0 :(得分:1)

FMDB Queue适用于多线程。目前我在多线程应用程序中使用它并发现没有问题。

请描述您使用FMDB队列遇到的问题

例如

      var FMDBQueue = FMDatabaseQueue(path:"db path")

      FMDBQueue.inTransaction{ (db, rollback) in
        do
        {
            let resultset = try db.executeQuery(queryString, values: [])
            while(resultset.next()){
                //do your task

             }

        }
        catch
        {
            rollback.memory = true
            print(error)
        }

    }

答案 1 :(得分:0)

FMDatabaseQueue序列化所有数据库访问。您无法与FMDatabaseQueue同时执行多个读取操作,并且永远不会:这不是FMDatabaseQueue的目的。

不幸的是,FMDB没有提供任何其他安全的并发模型。您可以使用原始FMDatabase连接,并处理写序列化和并行读取。例如,您可以将数据库调用包装在并发DispatchQueue中:

import "gitlab.com/kokizzu/gokil/I"
import "sync/atomic"

var CACHE_IDX int64
var CACHE_KEYS cmap.CMap

func init() {
    CACHE_KEYS = cmap.New()
}

// change a really long string to a shorter one 
func RamKey_ByQuery(query string) string {
    nkey := CACHE_KEYS.Get(query)
    if nkey != nil {
        return nkey.(string)
    }
    new_idx := atomic.AddInt64(&CACHE_IDX, 1)
    ram_key := `:` + I.ToS(new_idx) // convert integer to string
    CACHE_KEYS.Set(query, ram_key)
    return ram_key
}

此解决方案有一些警告:并发读取的数量不受限制,您不会从事务或保存点周围的DatabaseQueue高级API中获利,let dbQueue = DispatchQueue(label: "database", attributes: .concurrent) func read(block: () -> ()) { // Since the queue is concurrent, several readers can execute at // the same time. dbQueue.sync(execute: block) } func write(block: () -> ()) { // The barrier flag makes sure that only one writer block is executing // at a given time, and that no reader is currently executing. dbQueue.sync(flags: .barrier, execute: block) } let db = FMDatabase(...) read { // Select from db } write { // Write in db } 方法不会阻止您执行数据库更新。

您可以检查FMDB的替代方案:GRDB.swift库。它与FMDB非常相似。但是,与FMDB不同,它提供了一个DatabasePool类,可以避免上面列出的所有警告:https://github.com/groue/GRDB.swift#database-pools

read

答案 2 :(得分:-1)

检查此链接对您有用:

http://www.theappguruz.com/blog/use-sqlite-database-swift

获取数据:

@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,
                                           withArgumentsIn: nil)

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

}