数据存储

Cordova 应用程序可以使用多种存储 API。请参阅 html5rocks 存储概述教程,以获取更完整的概述和示例。

每个 API 都具有优缺点,这里总结如下。您应该选择最适合您需求的 API。您也可以在单个应用程序中使用多种不同的方法来实现不同的目的。

LocalStorage

本地存储提供简单的同步键值对存储,并且所有 Cordova 平台上的底层 WebView 实现都支持它。

使用摘要

可以通过 window.localStorage 访问本地存储。以下代码片段显示了返回的 Storage 对象公开的最重要方法

var storage = window.localStorage;
var value = storage.getItem(key); // Pass a key name to get its value.
storage.setItem(key, value) // Pass a key name and its value to add or update that key.
storage.removeItem(key) // Pass a key name to remove that key from storage.

有关更多信息,请参阅

优点

  • 所有 Cordova 平台都支持。
  • 它简单、同步的 API 使其易于使用。

缺点

  • 仅存储字符串,因此复杂的数据结构必须序列化,并且只能存储可以序列化的数据。
  • 处理大量数据时性能较差。特别是
    • 由于缺乏索引,搜索需要手动遍历所有数据。
    • 由于需要序列化/反序列化,存储大型或复杂项目很慢。
    • 同步 API 意味着调用将锁定用户界面。
  • 存储总量有限(通常约为 5MB)。
  • iOS 将 localStorage 数据存储在操作系统可能在需要空间时清理的位置。

IndexedDB

IndexedDB API 的目标是结合 LocalStorage 和 WebSQL API 的优点,同时避免它们的缺点。IndexedDB 允许您存储任意 JavaScript 对象(只要它们受 结构化克隆算法 支持),并使用键进行索引。它提供了一些 SQL 表的优点,而无需限制结构或需要预先定义结构。

IndexedDB 提供了一个简单易懂的数据模型,类似于 LocalStorage。但与 LocalStorage 不同的是,您可以创建多个数据库,每个数据库有多个存储,并且它的异步 API 和搜索索引提供了性能优势。

所有平台上的底层 WebView 都支持 IndexedDB,但在 browser 平台上存在已知限制。

Web 浏览器限制

实际行为可能取决于使用的浏览器。例如,Safari 和 Firefox 浏览器的行为可能存在差异。

使用摘要

  • IndexedDB 异步工作 - 您请求特定的数据库操作,然后通过 DOM 事件收到结果通知。
  • 当您发出请求时,您会获得一个请求对象,该对象提供 onerroronsuccess 事件,以及 resulterrorreadyState 等属性。

以下代码片段演示了 IndexedDB 的一些简单用法

var db;
var databaseName = 'myDB';
var databaseVersion = 1;
var openRequest = window.indexedDB.open(databaseName, databaseVersion);
openRequest.onerror = function (event) {
    console.log(openRequest.errorCode);
};
openRequest.onsuccess = function (event) {
    // Database is open and initialized - we're good to proceed.
    db = openRequest.result;
    displayData();
};
openRequest.onupgradeneeded = function (event) {
    // This is either a newly created database, or a new version number
    // has been submitted to the open() call.
    var db = event.target.result;
    db.onerror = function () {
        console.log(db.errorCode);
    };

    // Create an object store and indexes. A key is a data value used to organize
    // and retrieve values in the object store. The keyPath option identifies where
    // the key is stored. If a key path is specified, the store can only contain
    // JavaScript objects, and each object stored must have a property with the
    // same name as the key path (unless the autoIncrement option is true).
    var store = db.createObjectStore('customers', { keyPath: 'customerId' });

    // Define the indexes we want to use. Objects we add to the store don't need
    // to contain these properties, but they will only appear in the specified
    // index of they do.
    //
    // syntax: store.createIndex(indexName, keyPath[, parameters]);
    //
    // All these values could have duplicates, so set unique to false
    store.createIndex('firstName', 'firstName', { unique: false });
    store.createIndex('lastName', 'lastName', { unique: false });
    store.createIndex('street', 'street', { unique: false });
    store.createIndex('city', 'city', { unique: false });
    store.createIndex('zipCode', 'zipCode', { unique: false });
    store.createIndex('country', 'country', { unique: false });

    // Once the store is created, populate it
    store.transaction.oncomplete = function (event) {
        // The transaction method takes an array of the names of object stores
        // and indexes that will be in the scope of the transaction (or a single
        // string to access a single object store). The transaction will be
        // read-only unless the optional 'readwrite' parameter is specified.
        // It returns a transaction object, which provides an objectStore method
        // to access one of the object stores that are in the scope of this
        //transaction.
        var customerStore = db.transaction('customers', 'readwrite').objectStore('customers');
        customers.forEach(function (customer) {
            customerStore.add(customer);
        });
    };
};

function displayData() {
}

有关更多信息,请参阅

优点

  • 性能良好 - 异步 API 不会阻塞 UI,索引提供了良好的搜索性能。
  • 简单的数据模型比 SQL 更易于学习。
  • 比 WebSQL 更灵活的结构。
  • 多个数据库和对象存储提供了比 LocalStorage 更结构化的结构。
  • 使用事务性数据库模型的稳健性。
  • 支持版本控制。

缺点

  • 复杂的 API,嵌套回调。
  • 存储总量有限,并且可能被清除 如 MDN 上所述

基于插件的选项

FileSystem API

FileSystem API 是一个 W3C 规范,由 Chrome 实现,但其他浏览器没有实现。它提供 API 来存储和检索本地文件系统上的数据,并在 html5rocks 文章 中进行了详细描述。虽然该 API 未被任何 Cordova 平台原生支持,但 File 插件 提供了一个广泛的实现,可在所有 Cordova 平台上使用。

SQLite 插件

SQLite 插件提供的 API 与上面描述的 WebSQL 几乎相同。主要区别在于

  • 它支持 Windows 平台。
  • 它实际上没有大小限制。

它有以下几种变体

  • cordova-sqlite-storage - 核心版本,包含自己的 sqlite3 实现。它支持 iOS、Android 和 Windows 平台。
  • cordova-sqlite-ext - 扩展版本,具有额外的功能,包括在 Android 和 iOS 上支持 REGEXP。
  • cordova-sqlite-evfree - 与 cordova-sqlite-ext 类似,但具有改进的内存处理。在 GPL v3 或商业许可下提供。

其他插件

搜索 Cordova 插件 以查找提供其他存储选项的插件。