这是一个围绕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_XXXC 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放弃其在操作过程中获取的任何资源。