33

我想将用户手机中的一些大型离线数据(超过 100 MB)存储在加密数据库中。如果可能的话,我还想分发预先填充的数据库。我也看到了这个

我知道webdatabase的事情,但是因为它已经贬值了,所以建议我不要使用它。

我也见过一些第三方插件,比如SQLite Plugin,但它只适用于 iOS 和 Android 设备,但我针对 4 个平台(ios、android、blackberry、windows)

除了写下我自己的解决方案之外,还有其他解决方案吗?

4

5 回答 5

34

我最近做了一个需要这个的应用程序,针对相同的操作系统。您可以使用 2 个数据库的组合:

1.本地存储::

检查本地存储

function supports_html5_storage() {
  try {
    return 'localStorage' in window && window['localStorage'] !== null;
  } catch (e) {
    return false;
  }
}

将项目设置为 LocalStorage

localStorage.setItem("bar", foo);

或者

localStorage["bar"] = foo;

从 LocalStorage 获取项目

var foo = localStorage.getItem("bar");

或者

var foo = localStorage["bar"];

2. SQLite 数据库(更方便,更持久)

设置你的数据库

var shortName = 'BHCAppDB'; 
var version = '1.0'; 
var displayName = 'BHCAppDB'; 
var maxSize = 65535; 
if (!window.openDatabase){ 
     alert('!! Databases are not supported in this Device !! \n\n We are sorry for the inconvenience and are currently working on a version that will work on your phone'); 
}
db = openDatabase(shortName, version, displayName,maxSize);
createAllTables(db);

创建您的表格

function createAllTables(db){
    db.transaction(function(transaction){
        transaction.executeSql("CREATE TABLE IF NOT EXISTS Profile(id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT, gender TEXT,age INTEGER)");
}

执行 SQL 查询

transaction(function(transaction){
        var rowCount = 'SELECT * FROM Profile';
        transaction.executeSql(rowCount,[],function(transaction,result){
            if(result.rows.length == 0){
                var sqlString = 'INSERT INTO Profile (name,gender,age) VALUES("自己","Female",18)';
                transaction.executeSql(sqlString);

            }
        });
    });

编辑::我忘了添加最后一个选项:)

3. 所有设备上的原生存储

这是Phonegap最好的部分。您可以使用 Phonegap 插件调用在所有设备上调用本机插件类。在调用过程中,您可以将参数传递给类,并且本机类可以将您的数据存储在操作系统本身中。

例如 :: 在 iOS 中,您创建一个插件 .h 和 .m 类并将其注册到 Cordova.plist 文件。完成后,您需要使用 Phonegap 从 JavaScript 向该类发送调用。一旦使用 NSDictionary 或任何其他 NSArray 类型接收到参数,您就可以调用 CoreData 类来存储无限量的数据。你永远不会耗尽内存。

这也可以对所有其他操作系统以类似的方式完成:)

对于加密,请尝试以下操作 :: SQLCipher

以下是有关使用现有 SQLite 数据库的一些附加信息。在此示例中,encrypted.db 是您创建和编译的全新数据库。

ATTACH DATABASE 'encrypted.db' AS encrypted KEY 'secret'; -- create a new encrypted database
CREATE TABLE encrypted.t1(a,b); -- recreate the schema in the new database (you can inspect all objects using SELECT * FROM sqlite_master)
INSERT INTO encrypted.t1 SELECT * FROM t1; -- copy data from the existing tables to the new tables in the encrypted database
DETACH DATABASE encrypted;
于 2013-04-04T12:50:21.817 回答
4

在 Web 数据库的W3C规范中提到,Web 应用程序工作组继续致力于其他两个与存储相关的规范:Web 存储索引数据库 API

所以 webdatabase 规范不再有效,但其他两个规范是有效的。

Web Storage 可用于在用户浏览器中本地存储数据。有以下目标可以实现:

  • localStorage 存储没有过期日期的数据
  • sessionStorage 存储一个会话的数据

不建议您使用 Web 存储(超过 100MB),因为 W3C 规范提到:

建议对每个源使用 5 兆字节的任意限制。

在我看来,SQLite 是最好的可用选项,因为它是一个进程内库,它实现了一个自包含、无服务器、零配置、事务性 SQL 数据库引擎。此外,SQLite 限制似乎可以满足您的需求:

SQLITE_MAX_PAGE_COUNT 的最大可能设置为 2147483646。当与最大页面大小 65536 一起使用时,这使 SQLite 数据库的最大大小约为 140 TB。

关于您的加密要求,您应该考虑作为 SQLite 扩展的SQLCipher 。

SQLCipher 是一个 SQLite 扩展,它为数据库文件提供透明的 256 位 AES 加密。迄今为止,它已由 Zetetic LLC 开源、赞助和维护。在移动领域,SQLCipher 在 Apple 的 iOS 以及诺基亚/QT 中得到了广泛的应用相当长的一段时间。

另一种选择是在写入和读取数据库时加密和解密数据。

我希望这有帮助。

于 2012-08-22T18:51:12.743 回答
1

我正在开发的移动应用程序也有类似的要求。它需要离线访问包含近 500,000 个不同零件的零件表。该表的源是通过定义明确的 GET URL 获取其 JSON 从服务器中提取的。

我考虑过 Indexed DB,但 iOS 和 Android 中的移动浏览器不支持这一点。Web 本地存储不是一个选项,因为它有 5 MB 的硬性限制。因此,我决定使用 Web SQL 数据库标准 ( http://www.w3.org/TR/webdatabase/ ),尽管它已被弃用。到目前为止,我使用 Web SQL 数据库的经验非常好。数据库操作在我支持的移动设备(iPad 2、iPad 3、摩托罗拉 Xyboard、三星 Galaxy Tab 2)上执行得非常好并且非常可靠。此外,Phonegap 公开了一个 JavaScript API 以使用此标准(请参阅http://docs.phonegap.com/en/2.5.0/cordova_storage_storage.md.html#Storage)。

我编写了一个 Java 实用程序,将下载的 JSON 数据转换为 SQLite 数据库,该数据库的文件打包为 Android APK 或 iOS 应用程序包的一部分。

当我的 Phonegap 移动应用程序启动时,它使用本机代码检查应用程序的私有数据目录是否存在 SQLite 数据库文件。如果文件不存在,本机代码会从应用程序包中复制数据库文件。

我的实现基于我在下面的链接中找到的示例代码。我希望这有帮助。如果您对我的特定实施有任何疑问,请告诉我。

http://gauravstomar.blogspot.com/2011/08/prepopulate-sqlite-in-phonegap.html

于 2013-04-08T18:15:05.067 回答
1

我尝试使用LokiJS作为本地数据库,发现它对非关系数据很有帮助。在我的情况下,我检索使用 MongoDB 在服务器上存储的数据,但这取决于您系统的性质

于 2017-10-25T10:57:49.277 回答