我在iOS中使用FMDB数据库库用于sqlite。如何在FMDB中同时执行多个读取操作。目前我正在使用FMDB数据库队列。
答案 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())")
}
}