Windows8应用程序数据访问与存储的几种可选方式

原文地址:http://msdn.microsoft.com/en-us/magazine/jj991982.aspx?utm_source=feedly

作者:Rachel Appel

 

管理数据是应用开发中非常关键的一个环节。无论是游戏,新闻,旅游还是关于时尚的应用,都总是与数据密不可分。Win8应用经常需要管理一些存储在不同位置且格式多种多样的散乱数据。我将在这篇文章中讲述多种数据存储方式以及创建Win8应用时可用的数据访问API,涉及所有语言,以及对于内容和配置的数据管理策略。

 

数据管理和存储需要考虑的事项

作为一个应用开发人员,你需要在项目开始之前决定你的数据需求,因为修改底层架构会导致大量的重复性工作。你可能有一个已经存在的数据源,在这种情况下它们为你做出决定,但是对于一个还未开工的项目,你必须要考虑要把数据存储在什么地方。你有两个选择,存储在本地或远程的某个地方:

本地:通常情况下这种数据存储在文件或本地数据库,但是在Win8中,你可以通过内置的文件选择器(File Picker)或合约把其他应用当作数据的来源。在Javascript应用中,Web Storage和IndexedDB API也可以作为本地数据源。

远程:这些数据可以通过Windows Azure, SkyDrive或者是一些可以提供JSON或XML数据的远端HTTP端点存储在云端,也包括一些像Facebook或Flicker的公共API.

数据的大小经常决定了数据需要存储在本地还是远端;然而,大部分Win8应用会既使用本地数据也使用远端数据。这是因为相对较小,更易移动的设备例如笔记本,平板电脑,手机都是有规范的,他们很少应用很大的存储空间。尽管如此,它们仍然需要让应用在离线状态时能够正常运行。例如,Surface,像很多便携式设备一样,拥有32G或64G存储空间。一些简单的基于文本的数据,例如JSON一般不会很大,但是关系数据库和多媒体数据(比如图片,音频和视频)会很快占满设备的存储空间。

让我们看下用于存储应用程序数据的各种本地和远端存储方式。

 

Web Storage

Web Storage听起来可能像简单的在Web上的存储,其实不是。Web Storage,是一个HTML5标准,是一种将数据存储在本地客户端的很好的方式。Windows8应用程序和以前的HTML页面都支持Web Storage. 不需要去设置数据库,也不需要去复制文件,Web Storage是一种内存中的数据库。

Web Storage可以用Javascript通过window对象的以下两种属性获得:

1. localStorage: 本地数据,在应用终止后持久化并可以提供给之后的应用实例使用。

2. sessionStorage: 也是本地数据,但是sessionStorage会在应用终止后被毁坏。

你可以通过附加动态属性的方式把简单类型或复杂对象的数据存储在sessionStorage或者localStorage变量中。动态属性是类似于下面语法的键值对:

sessionStorage.lastPage = 5;
WinJS.xhr({ url: "data/data.json" }).then(function (xhr) {
  localStorage.data = xhr.responseText;
};

lastPage属性会一直存在直至应用程序终止,因为他是保存在sessionStorage中的,然而存储在localStorage中的data属性则会一直存在。

能够在应用会话中持久化数据到本地的能力让Web Storage成为支持离线场景的非常好的选择。小型数据也更适合离线场景。因为JSON数据很紧凑,很容易将整个JSON数据集塞进一个Web Storage提供的5Mb大小的空间,而且还有大量剩余空间留给多媒体数据来存放。

因为Web Storage是一种HTML5标准,所以只能在用Javascript开发的Win8项目中使用。

 

IndexedDB

另一个HTML5标准是IndexedDB,它是用来存储大型的可搜索的持久化数据集的本地存储。作为HTML的一个组件,你能够在浏览器客户端的Web应用程序和Win8应用程序中使用IndexedDB. IndexedDB在一个对象数据库中保存数据项,而且它非常灵活,你可以存储从文本到二进制大对象的任何数据类型。例如,多媒体文件一般都很大,所以将音频和视频存储在IndexedDB是一个很好的选择。

因为IndexedDB是一个对象数据库,它不使用SQL语句,所以你必须要通过一种面向对象类型的语法来访问数据。和IndexedDB进行交互是通过事务和游标进行的进行的,如下:

var dataStore = "Datastore";
var trn = db.transaction(dataStore, IDBTransaction.READ_ONLY);
var store = trn.objectStore(dataStore);
trans.oncomplete = function(evt) { // transaction complete };
var request = store.openCursor();
request.onsuccess = function(evt) {
  var cursor = evt.openCursor();
};
request.onerror = function(error) { // error handling };

因为IndexedDB是针对大数据的,用它来存储小数据项表现出的效率会比较低,存储位或字节级数据的话,Web Storage是更好的选择。IndexedDB也很适合存储内容数据,但是不适合存储应用的配置数据。

 

SQLite

SQLite是一种基于文件的自包含事务关系数据库,它不需要配置也不需要一个专门的数据库管理员去维护。你可以把SQLite和任何Windows Runtime语言一起使用,它可以通过Visual Studio extension来获得。当你在JavaScript开发的应用中使用SQLite时,你需要从GitHub上下载一个SQLite3-WinRT。

有ASP.NET或Windows Forms开发经验的开发人员被关系型数据库吸引着,但是在做Windows Store App开发时,由于移动设备存储空间的限制,数据类型和形式的多样化,特别是多媒体数据,导致关系数据库管理系统(RDBMS)不总是最好的选择。因为SQLite是一个关系数据库,它对于那些需要关系和事务行为的应用看起来还不错。这意味着,SQLite对于line-of-business(LOB)应用或者数据录入的应用来说是非常棒的选择,也可以作为一个仓库来将那些来自于线上的数据存储在本地供离线使用。

如果SQLite数据库对于便携式设备过于庞大,你可以把它放在服务器端或云端。代码不需要改变太多,因为SQLite3类库使用了传统的连接和增删改查对象,类似于以下代码:

// C# code that opens an async connection.
var path =
  Windows.Storage.ApplicationData.Current.LocalFolder.Path + @"\data.db";
var db = new SQLiteAsyncConnection(path);
// JavaScript code that opens an async connection.
var dbPath =
  Windows.Storage.ApplicationData.current.localFolder.path + '\\data.db;
SQLite3JS.openAsync(dbPath).then(function (db) {
  // Code to process data.
});

如你所见,SQLite使用起来就像使用其他的SQL数据库一样。SQLite数据库的最大上限高达140TB. 请谨记,非常大的数据库通常需要专业的数据库管理员来维护,以保证数据库的完整性,高效性以及安全性。大部分数据库管理员和开发人员在操作关系型数据库时都喜欢使用可视化工具去创建和管理数据库对象或对数据进行即席查询,Sqliteman对于基本的SQLite操作来说是一个非常理想的管理工具。

如果你是要把一个已经存在的用Windows Forums,WPF或Silverlight写的Windows桌面应用转为一个Windows Store应用,你可能已经使用了SQL CE数据库。如果是这样,你可以利用ExportSqlCE工具将数据从SQL CE中导入SQLite,然后使用Sqliteman来管理他们。

 

文件作为数据和文件 API

何必非要纠结于数据库?特别是应用的用户坚持要用他们的已有文件。对于照片和文档尤是如此。File API不仅仅是简单的提供一个文件夹或文件的导航器;它还能够让用户选择一个应用作为文件的存储位置。这意味着应用之间可以相互对话并交换数据。一个文件打开选择器可以像和我的文档,视频或者音乐等常规的文件夹一样和Bing,照相机或照片应用进行交互。在应用,服务和私人文件间能够简单地分享数据是Windows最炫的特性。

很多操作系统提供了一个机制去注册应用能够使用的文件类型,并在用户点击这些文件图标时启动该应用。在Windows中,这种机制被称为文件关联。Windows8扩展了这个概念,它允许应用之间通过一个叫做合约的系统层面的特性来进行对话。实现合约的一种方式是通过文件选择器。注意下面这些代码和桌面应用程序或早期的Windows版本中的文件对话框API很相似(注意:为了简介性,一些代码在这个例子中被忽略掉了;完整的关于FileOpenPicker类的使用请参见这里:http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.pickers.fileopenpicker.aspx):

fileOpen: function () {
  var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
  openPicker.viewMode = Windows.Storage.Pickers.PickerViewMode.thumbnail;
  openPicker.suggestedStartLocation =
    Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
  openPicker.fileTypeFilter.replaceAll([".png", ".jpg", ".jpeg"]);
  openPicker.pickSingleFileAsync().done(function (file) {
  // ...
  });
}

从Windows8选择器中选择一种应用将会启动该应用。例如,如果用户选择Bing,选择器会启动Bing应用并向应用返回用户的图片选择。

 

现在我们看完了本地存储的方式,现在来看一看存储远程数据的方式。

 


Web Services和ASP.NET Web API

大部分程序员都很熟悉通过XML Web Service来使用和修改数据,因为他们经历过Microsoft .NET Framework1.x的时代。使用Web Services的最主要优势是,数据存储在一个远程的中心位置,只要在连接状态,多个设备上的应用能够在任何时刻访问数据。访问底层数据库是通过一组HTTP端点间的管道来交换JSON或XML数据。很多公共API例如Twitter或Flickr,都会暴露出JSON或者XML数据来供你在Windows Store应用中使用。

Web Services有多种类型:

ASMX services:利用传统的ASP.NET通过HTTP来发送数据。

Windows Communication Foundation(WCF)和富互联网应用程序(RIA)服务:以基于消息的方式在HTTP端点间传输数据。

OData:开放数据协议,通过HTTP传输数据的另一种API.

ASP.NET Web API:一种新的ASP.NET MVC4框架,它可以轻松地创建RESTful HTTP服务,向应用或网站传输JSON或XML数据。

如果你从头开始开发后端服务,ASP.NET Web API可以精简你的开发流程,因为他能够轻松构建Restful Services并提供给应用使用。

无论是什么后端服务,只要是通过HTTP的,你就可以用C#的HttpWebRequest对象和HttpWebResponse对象和Web Services进行通信。在JavaScript应用中,WinJS的XMLHttpRequest包装适合异步操作,如以下代码一样:

WinJS.xhr({ url: "data.json" }).then(function (xhr) {
  var items = JSON.parse(xhr.responseText);
  items.forEach(function (item) {
    list.push(item);
  })
});

对于Web Services来说存储空间通常并不是问题,因为Web Services只是一个能够在端点之间传输数据的软件。这意味着它的底层数据库能够在任何地方,可以在远程服务器上,Web主机或Windows Azure实例。

你可以在Windows Azure上托管上面提到的诸如ASP.NET Web API实例或WCF服务等Web Services,和它们的数据一起。

 

SkyDrive

不要忘记SkyDrive不仅是一种存储数据的方式,而且是非常好的方式。将SkyDrive认为是一种非存储的存储方式。用户可以将SkyDrive作为云端的存储位置,通过文件打开器或文件存储器来选择来访问文件。允许用户将文件存储在SkyDrive上意味着不用再去担心数据库管理,每个用户都有7Gb的存储空间,空间非常足够。

SkyDrive用户还可以购买更多的存储空间。

Live API包含了支持Rest的SkyDrive API的一整套特性,可以用来向SkyDrive进行读写操作。调用SkyDrive去获取所有共享项目的列表就像下面代码这样:

 

GET https://apis.live.netv5.0/me/skydrive/shared?access_token=ACCESS_TOKEN

Microsoft.Live命名空间允许C#开发人员访问Live和SkyDrive API,JavaScript程序员可以用HTTP的POST或PUT发出支持REST的调用。应用程序的配置数据不建议存储在SkyDrive上。

 

Windows Azure Mobile Services

Windows Azure Mobile Services对于跨平台和多平台的应用来说是非常好的选择。基于Windows Azure,这种方式提供的不只是可扩展的存储;它还提供推送通知,业务逻辑管理,一个身份验证API和一个完整的SDK. 除了这些特性外,它还提供了一个易于使用的基于Web的管理工具。

Mobile Services SDK集成了对Windows应用商店,Windows Phone8,IOS和Android应用的支持。所有的主流平台都支持,而且你可以用Mobile Services SDK在几分钟内创建一个可运行的原型,并随即将数据交付给多平台应用程序。

在SDK的诸多功能中,你可以使用查询对象去从表中查询数据,就像下面这样:

var query = table.orderBy('column').read({ success: function(results) { ...}});

如你所见,代码就像使用其他API一样,所以学习的曲线和这里讨论的其他可选方式相同。你可以使用任何Windows Store应用语言来访问SDK和Mobile Services.

 

应用程序数据管理和存储方式

前面提到的所有数据存储和访问方式都是存储内容的,但作为一个开发人员,你还需要处理应用的配置数据。这是描述你的也能够用或其设备能力的元数据,不是用户数据。Windows8应用会使用持久应用数据(比如用户偏好)和临时元数据(比如用户最后一次滚动滚动条的位置或者搜索项)。这些小的但有效的便利措施能够为用户提供可能的最好体验,所以把它们创建在你的应用程序中非常重要。

虽然一些这样的数据属于设备,但考虑到很多应用会跨平台和跨设备的事实,将应用程序数据集中存放在Windows Azure并与内容数据保持同步性更加合理。

一组专门用于管理应用程序数据的API存在于一个命名空间为Windows.Storage的ApplicationData的类中,代码如下:

var localSettings = Windows.Storage.ApplicationData.current.localSettings;
var roamingSettings = Windows.Storage.ApplicationData.current.roamingSettings;

你可以在localSettings或roamingSettings属性中存储简单或复杂的类型。

用local或者roaming settings是存储应用程序配置数据的首选方式。IndexedDB,文件或SkyDrive等技术都不是存储应用程序配置数据的好方式,如果应用程序已经使用了SQLite来存储内容数据,则在SQLite中存储配置数据还算合理。你还必须要考虑应用程序在离线状态下会做什么。换句话说,你的一些数据需要缓存,但是不要消耗太多磁盘空间。

 

内容和配置

总的来说,去实现一个合适的数据架构,你不应该依赖于移动设备有限的存储空间,所以将数据托管在云端通常是一种很好的方式。但是,如果你有一个比较老式的数据库,重用它可能不可避免。对于内容和配置,Windows商店应用支持各种结构化和BLOB存储需求。


你可能感兴趣的:(windows,存储,8)