这是一个围绕SQLite的Objective-C封装
FMDB
安装
如果尚未执行此操作,则可能需要初始化项目,以使其Podfile
为您生成模板:
$ pod init
然后,编辑Podfile
,并添加FMDB
:
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'MyApp' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for MyApp2
pod 'FMDB'
# pod 'FMDB/FTS' # FMDB with FTS
# pod 'FMDB/standalone' # FMDB with latest SQLite amalgamation source
# pod 'FMDB/standalone/FTS' # FMDB with latest SQLite amalgamation source and FTS
# pod 'FMDB/SQLCipher' # FMDB with SQLCipher
end
$ pod install
然后打开.xcworkspace
而不是.xcodeproj
。
Carthage 安装
$ echo ' github "ccgus/fmdb" ' > ./Cartfile
$ carthage update
您可以在Cocoa项目中使用任何一种样式。FMDB会在编译时确定您正在使用哪个,并做正确的事。
自定义功能
过去,编写自定义函数时,通常必须包含自己的@autoreleasepool
块,以避免在编写通过大表扫描的函数时出现问题。现在,FMDB将自动将其包装在自动释放池中,因此您不必这样做。
另外,过去,在检索传递给函数的值时,您必须下拉至SQLite C API并包含您自己的sqlite3_value_XXX
调用。现在有FMDatabase
方法valueInt
,valueString
等等,这样你就可以留内斯威夫特和/或Objective-C中,而无需自行调用C函数。同样,指定的返回值时,你不再需要调用sqlite3_result_XXX
C API,而是你可以使用FMDatabase
方法resultInt
,resultString
等有一个新enum
的valueType
叫SqliteValueType
,可用于检查传递给自定义函数参数的类型。
queue.inTransaction { db, rollback in
do {
guard let db == db else {
// handle error here
return
}
try db.executeUpdate("INSERT INTO foo (bar) VALUES (?)", values: [1])
try db.executeUpdate("INSERT INTO foo (bar) VALUES (?)", values: [2])
} catch {
rollback?.pointee = true
}
}
然后,您可以在SQL中使用该函数(在这种情况下,匹配“ Jose”和“José”):
SELECT * FROM employees WHERE RemoveDiacritics(first_name) LIKE 'jose'
API变更
除了makeFunctionNamed
上面提到的以外,还有一些其他的API更改。具体来说,
为了与API的其余部分保持一致,方法
objectForColumnName
和UTF8StringForColumnName
已重命名为objectForColumn
和UTF8StringForColumn
。注意,如果将无效的列名/索引传递给它,则
objectForColumn
(和相关的下标运算符)现在返回nil
。它曾经返回NSNull
。为了避免与混乱
FMDatabaseQueue
的方法inTransaction
,其中执行交易,该FMDatabase
方法以确定是否是在交易与否,inTransaction
已被替换为只读属性,isInTransaction
。几种功能都被转换为性能,即,
databasePath
,maxBusyRetryTimeInterval
,shouldCacheStatements
,sqliteHandle
,hasOpenResultSets
,lastInsertRowId
,changes
,goodConnection
,columnCount
,resultDictionary
,applicationID
,applicationIDString
,userVersion
,countOfCheckedInDatabases
,countOfCheckedOutDatabases
,和countOfOpenDatabases
。对于Objective-C用户而言,这几乎没有实质性影响,但是对于Swift用户而言,它带来了更为自然的界面。注意:对于Objective-C开发人员,以前版本的FMDB公开了许多ivars(但是我们希望您无论如何都不要直接使用它们!),但是这些实现的详细信息不再公开。
URL方法
为了适应Apple从路径到URL的转变,现在存在NSURL
各种init
方法的再现形式,以前只接受路径。
用法
FMDB中有三个主要类:
FMDatabase
-表示单个SQLite数据库。用于执行SQL语句。FMResultSet
-表示在上执行查询的结果FMDatabase
。FMDatabaseQueue
-如果要在多个线程上执行查询和更新,则需要使用此类。在下面的“线程安全”部分中对此进行了描述。
数据库创建
使用FMDatabase
指向SQLite数据库文件的路径创建。此路径可以是以下三个路径之一:
- 文件系统路径。该文件不必在磁盘上存在。如果它不存在,则会为您创建。
- 空字符串(
@""
)。在临时位置创建一个空数据库。FMDatabase
关闭连接后,将删除该数据库。 NULL
。创建一个内存数据库。FMDatabase
关闭连接后,该数据库将被销毁。
(有关临时和内存数据库的更多信息,请阅读有关此主题的sqlite文档:https : //www.sqlite.org/inmemorydb.html)
与数据库进行交互之前,必须先将其打开。如果没有足够的资源或权限打开和/或创建数据库,则打开失败。
执行更新
任何不是该SELECT
语句的SQL语句都可以视为更新。这包括CREATE
,UPDATE
,INSERT
,ALTER
,COMMIT
,BEGIN
,DETACH
,DELETE
,DROP
,END
,EXPLAIN
,VACUUM
,和REPLACE
语句(以及许多其他)。基本上,如果您的SQL语句不是以开头SELECT
,则它是一条更新语句。
执行更新将返回单个值a BOOL
。返回值YES
表示更新已成功执行,返回值NO
表示遇到某些错误。您可以调用-lastErrorMessage
和-lastErrorCode
方法来检索更多信息。
执行查询
一个SELECT
语句是一个查询和通过的一个执行-executeQuery...
方法。
FMResultSet
如果成功,则执行查询将返回一个对象,如果nil
失败,则返回一个对象。您应该使用-lastErrorMessage
和-lastErrorCode
方法来确定查询失败的原因。
为了遍历查询结果,可以使用while()
循环。您还需要从一条记录“步入”到另一条记录。使用FMDB,最简单的方法是这样的:
FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
while ([s next]) {
//retrieve values for each record
}
-[FMResultSet next]
在尝试访问查询中返回的值之前,必须始终调用它,即使您只希望得到一个值:
FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"];
if ([s next]) {
int totalCount = [s intForColumnIndex:0];
}
[s close]; // Call the -close method on the FMResultSet if you cannot confirm whether the result set is exhausted.
FMResultSet
有许多方法可以检索适当格式的数据:
intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dateForColumn:
dataForColumn:
dataNoCopyForColumn:
UTF8StringForColumn:
objectForColumn:
这些方法中的每一个都还具有一个{type}ForColumnIndex:
变体,用于根据结果中列的位置而不是列名来检索数据。
通常情况下,有没有必要-close
的FMResultSet
自己,因为当任一结果集耗尽出现这种情况。但是,如果仅提取单个请求或其他没有耗尽结果集的请求,则需要在上调用-close
方法FMResultSet
。
在数据库上执行完查询和更新后,应-close
建立FMDatabase
连接,以便SQLite放弃其在操作过程中获取的任何资源。