翻译自cordova官方文档(如果需要链接,请自行对照原文链接进行查看):
https://cordova.apache.org/docs/en/latest/cordova/storage/storage.html
Storage(存储)
Cordova Application支持很多用于存储的API。
在这里介绍的每种API都有各自的优势和劣势,你需要根据你的实际需要来选择最优方案。当然你也可以在不同的应用中以不同的方式实现这个目的。
LocalStorage
Local storage提供简单,同步的key/value对存储方式,并且被基于Cordova平台的WebView应用所支持。
用法
我们通过window.localStorage来访问Local storage,下面的Code是用来演示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的应用程序支持。
- 简单且是同步操作,所以非常简单。
缺点
- 只能存储字符串类型的数据,如果是具有复杂结构的数据需要进行序列化,然后在存储。(这里强烈建议使用JSON)
- 在大量数据的时候处理能力比较弱。比如:
- 没有数字索引号,所以遍历所有数据的时候比较麻烦。
- 存储大数据的时候因为需要进行序列化和反序列化所以效率会低一些。
- 同步操作,所以在没有执行结束之前会阻塞操作。
- 数据大小有5MB左右的限制。
- iOS通过localStorage存储的数据会在系统释放空间的时候被清除。
WebSQL
WebSQL提供了一个用于存储数据的结构化数据库。使用标准的SQL语法来操作。
目前被下列平台支持:
- Android
- BlackBerry 10
- iOS
用法
通过window.openDatabase()方法来获取WebSQL实例对象:
var db = window.openDatabase(name, version, displayName, estimatedSize);
- name (string): 唯一的数据库名字,它会被存储在存储介质上。
- version (string): 数据库的版本号。
- displayName (string): 一个会被系统提供给用户的数据库名称。
- estimatedSize (number): 数据库的大小,单位是[bytes],如果用户需要增加数据库大小,需要权限。所以这里需要做特殊处理,在空间不足的情况下弹出提示。
返回的Database提供一个transaction()(readTransaction()针对读进行优化的方法)来让我们进行事务操作:
var db = window.openDatabase(name, version, displayName, estimatedSize);
db.transaction(function(tx) {
tx.executeSql(sqlStatement, valueArray, function(tx, result) {
console.log(result);
}, function(error) {
console.log(error);
});
});
数据库的版本号
当打开一个现有数据库的时候,如果指定的版本号不存在,会抛出异常,并且数据库无法打开。
但是如果你指定的是一个空的字符串给version参数,那么会默认打开当前版本的数据库(可以通过db.version取得当前版本信息)。
如果数据库刚刚开始创建,那么他会设置一个默认的空字符串给version。
优点
- 性能出色,可以通过索引来提高检索速度,并且API都是异步的,不会阻塞主线程。
- 基于事务的数据库处理模型。
- 支持版本控制
缺点
- 不支持所有Cordova平台。
- 比其他方案复杂。
- API不赞成使用,将来会被移除。
- 需要预先声明严格的结构。
- 总数据限制(5M)。
IndexedDB
IndexedDB的目标是吸收LocalStorage和WebSQL的有点,避免他们的缺点。IndexDB让你存储任意JavaScript对象类型,并且不需要预先声明结构。
IndexedDB提供简单易用的数据模型,和LocalStorage很像,但是又不同。你可以创建多个数据库,他们都使用异步API,在查询时有性能优势。
IndexedDB支持以下平台:
- BlackBerry 10
- Windows (with some limitations)
- Android (4.4 and above)
使用说明
- IndexedDB采用异步模式,当你发起一个数据库操作的时候,它通过DOM的event来通知你执行结果。
- 当你得到一个请求结果的时候,会得到一个请求对象。里面包括onerror和onsuccess事件,当然还有result,error,readyState.
下面是一个例子:
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() {
}
更多内容请参考这里:
- [W3C: Spec][W3CIndexedDB]
- [MDN: IndexedDB API Reference][MDNIndexedDBAPI]
- [MDN: IndexedDB Basic Concepts][MDNIndexedDBBasicConcepts]
- [MDN: Using IndexedDB Guide][MDNUsingIndexedDB]
优点
- 非常好的性能,异步操作不会阻塞UI。
- 简单易学的SQL数据模型。Simple data model easier to learn than SQL.
- 比WebSQL更灵活的结构。
- 多个数据库对象,比LocalStorage提供更多结构的存储。
- 可以使用事务。
- 支持版本。
缺点
- 不支持iOS。
- 回调的使用是代码复杂。
- 大小限制(5M)。
使用插件来完成存储
FileSystem API
FileSytem是一个W3C标准API,并且被Chrome支持。但是其他浏览器并不支持。它提供了在本地文件系统存储和检索数据的API。目前这个API并不被广泛支持。File插件提供了对所有Cordova平台的支持。
SQLite Plugin
SQLite插件提供了WebSQL完全一样的API。不同点是:
- 为Windows平台提供了支持。
- 没有大小限制。
它给出了以下的不同:
- [cordova-sqlite-storage][SQLiteStorage] - 依赖于SQLite的核心版本,目前仅支持iOS和Android。
- [cordova-sqlite-ext][SQLiteExt] - 这是一个扩展版本,提供了对Windows的支持以及在Android和iOS平台使用正则(REGEXP)。
- [cordova-sqlite-evfree][SQLiteEVFree] - 和cordova-sqlite-ext类似,但是改善了内存处理,使用GPL v3或者商业license。