如何在iOS应用中连接FMDB中来自两个不同数据库的两个表



我的场景是这样的。出于安全考虑,我决定将应用程序数据放到bundle中,而将用户数据放到文档目录中。问题是如何从不同的数据库连接表?如果不可能的话,我必须在文档目录中创建一个数据库表吗?

Sqlite3允许将外部数据库附加到当前连接。想象一下,您有两个数据库,每个数据库都通过FMDatabase拥有自己的连接(对于多线程目的,您应该使用FMDatabaseQueue)。现在,将另一个数据库附加到第一个数据库的连接上。然后可以从数据库1连接到数据库2中的表。重要:所有这些都是通过sqlite每个sql语句发生的,与FMDB无关。

我将在github上提供示例代码:https://github.com/itinance/MultiDatabaseJoin

为简单起见,我将数据库文件放在/tmp-directory下。对于iOS-Simulator,这工作得很好,我还没有在真正的设备上测试过这段代码,在那里你会把数据库放在文档文件夹或类似的东西(但这不是重点)。

这里重要的是sqlite3中的以下查询:
[db1 executeStatements:@"ATTACH DATABASE '/tmp/tmp2.db' AS second_db"];

在数据库连接db1时,我们附加来自第二个数据库的数据库文件。

在此附加之后,您可以在数据库连接1中连接到数据库连接2中的表,如下所示:

SELECT a.id, a.name AS aname, b.name AS bname FROM a INNER JOIN second_db.b ON b.a_id = a.id

下面是我试过的全部代码:

FMDatabase *db1 = [FMDatabase databaseWithPath:@"/tmp/tmp1.db"];
FMDatabase *db2 = [FMDatabase databaseWithPath:@"/tmp/tmp2.db"];
[db1 open];
[db2 open];
[db1 executeStatements:@"CREATE TABLE a (id INTEGER, name TEXT)"];
[db1 executeStatements:@"INSERT INTO a (id, name) VALUES (1, 'foo'), (2, 'bar')"];
[db2 executeStatements:@"CREATE TABLE b (id INTEGER, a_id INTEGER, name TEXT)"];
[db2 executeStatements:@"INSERT INTO b (id, a_id, name) VALUES (1, 1, 'b_foo'), (2, 2, 'b_bar')"];
bool success = [db1 executeStatements:@"ATTACH DATABASE '/tmp/tmp2.db' AS second_db"];
if(!success) {
    NSLog(@"%@", db1.lastErrorMessage);
    return YES;
}
FMResultSet* rs = [db1 executeQuery:@"SELECT a.id, a.name AS aname, b.name AS bname FROM a INNER JOIN second_db.b ON b.a_id = a.id"];
while( [rs next]) {
    NSLog(@"%@, %@", [rs stringForColumn:@"aname"], [rs stringForColumn:@"bname"]);
}
[rs close];

最新更新