热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

DojoDataStore——统一数据访问接口

本文已经首发于InfoQ中文站,版权所有,原文为《DojoDataStore——统一数据访问接口》,如需转载,请务必附带本声明,谢谢。InfoQ中文站是一个面向中

 

本文已经首发于InfoQ中文站,版权所有,原文为《Dojo Data Store —— 统一数据访问接口》,如需转载,请务必附带本声明,谢谢。  
InfoQ中文站是一个面向中高端技术人员的在线独立社区,为Java、.NET、Ruby、SOA、敏捷、架构等领域提供及时而有深度的资讯、高端技术大会如QCon 、线下技术交流活动QClub、免费迷你书下载如《架构师》等。​

 

无论在传统的桌面应用还是在主流的互联网应用中,数据始终占据着软件应用中的核心地位。当下,web2.0已经是一个让人们耳熟能详的词汇,而由此带来的数据的开放与共享,引领我们走入了海量数据时代。在今天的互联网上,数据的交互几乎成为了我们的终极诉求,可随之而来的数据多样性,信息的分布式存储及松耦合,以及数据量的几何级规模的膨胀也带来了数据组织上的难度的增大,与此同时,伴随着Ajax, RIA及面向服务的网络应用的发展,其所要求的客户端数据处理逻辑的复杂性不断增加,使得开发难度不断加大。出于简化数据处理逻辑,增加应用的可维护及可扩展性的需求,目前流行的Javascript框架也基本都会具有各自的数据处理模块或接口。本文的目的就是为了介绍Dojo的数据处理模块:Dojo.data。作为Dojo的数据处理中间层,其主要的职责就是解析及管理由数据源传入的各种类型的数据,通过统一的数据访问与处理接口与数据展现层(Dojo Widget)进行通讯,便于各个Widget的管理与程序的移植。

Dojo Data中的数据管理

在面向服务应用大行其道的今天,协调数据的多样性是开发互联网应用中不可避免的首要问题。我们常见的数据格式包括Json, XML, Csv等,作为数据处理的中间层,能够让用户以统一的接口连接不同的数据源是一个基本需求。在Dojo.data模块中,预定义了不同的DataStore用于访问管理不同数据格式的数据源,而所有的DataStore都会实现相同的数据访问接口,这样就可以成功实现数据提供层与数据展现层之间的松耦合。表1中列出了Dojo中部分已实现的各种不同的DataStore。

表1. Dojo中部分已实现的DataStore

DataStore 描述
dojo.data.ItemFileReadStore 用于JSON数据的只读的DataStore
dojo.data.ItemFileWriteStore 用于JSON数据的可读写的DataStore
dojox.data.CsvStore 用于CVS数据的只读的DataStore
dojox.data.OpmlStore 用于OPML(Outline Processor Markup Language)数据的只读的DataStore
dojox.data.HtmlTableStore 用于HTML table数据的只读的DataStore
dojox.data.XmlStore 用于XML数据的可读写的DataStore
dojox.data.FlickrStore 用于读取flickr.com提供的数据的只读的DataStore。是一个很好的web service相关的DataStore的示例
dojox.data.QueryReadStore 用于读取由服务器端提供的JSON数据的只读的DataStore

 

尽管读取的数据源多种多样,但在DataStore中,通过统一数据访问接口,对数据的组织管理是一致的。每条数据项都被作为一个item对象,其中包含了一定的键(attribute)值(value)对用以对应数据条目中的各个属性值。下面以一段简单的JSON数据片段为例,来介绍这种对应关系:

 

在这段JSON数据中共有两条数据项(item),分别都包含有"id", "name", "type", "population"与"area"五个属性字段。

Dojo.data 组织架构

为了符合各种应用中对数据中间层的不同需求,Dojo.data包对数据访问处理接口进行了一定程度的划分,包括 read,write,identify,notifaction 等。各种DataStore可以根据其应用需求实现特定的接口。

表2. Dojo.data.api主要接口

Dojo.data主要接口 描述
Dojo.data.api.read 提供读取数据项或者其属性值的功能,同时也支持对数据集的搜索,排序,和过滤。
Dojo.data.api.write 提供创建,删除,更新数据项功能。
Dojo.data.api.identify 提供基于唯一的标示符来定位和查询数据项的功能。
Dojo.data.api.notification 提供当 datastore的数据项改变等事件发生时通知侦听器的功能。最基本的事件包括数据的创建,修改和删除等。这也是Dojo.data的一项很重要的功能,通过此接口可以将数据展现层与数据中间层更好的分离开来。

 

Dojo.data API简介

Read

数据的获取是数据中间层的核心,Dojo.data.Read接口为异步获取异构数据提供了很大的便利性和灵活性。在Read接口中,主要是通过异步方式进行数据的获取,同时也提供了数据的排序、分页、简单查询等基本功能的支持。

  • fetch: function(/* Object */ keywordArgs)
  • fetch方法可以说是Dojo.data包的核心方法,它主要采用异步方法来获取数据。该方法接收一个键值对对象参数,用户可以通过对此参数中各个属性进行指定以获取特定的数据集合,如分页,简单查询过滤,排序等。以下是部分主要的参数属性介绍:

  • onBegin与onComplete: fetch方法是采用异步的方式来进行数据的获取,用户可以通过onBegin与onComplete这两个参数指定fetch方法的数据获取回调函数,onBegin在数据返回前会被调用一次,传入两个参数,分别为应返回数据集的条目数及此次fetch的request对象;而onComplete方法是作为数据返回的回调函数,数据集作为第一个参数传入给该回调函数。
  • start与count: 通常来说几乎所有的实际应用都会要求分页返回数据以提供更好的用户体验,start和count这两个属性就是为支持分页功能而实现的。start用于指定返回数据的起始索引(由0开始),而count则用于设置返回的数据条目数。
  • query: 除了分页以外,按需返回特定的数据集也是一项重要功能,在Dojo.data中,这一功能则是通过query属性提供支持的。query的值一般可设置为一个键值对对象,“键”应被设置为数据条目中的某项属性,而“值”则为条件指定。Dojo.data提供了精确匹配与模糊匹配(通配符:*为任意字符,?为单个字符)两种方式对数据进行过滤,可以根据具体情况选择使用。
  • sort:由于可能出现多个Widget使用同一个DataStore,数据集并不会以特定的序列进行存储,当需要进行排序时,可以通过sort属性进行指定,DataStore则会相应的返回符合条件的数据集。sort 参数不仅指定了要排序的字段,而且还必须指定排序的顺序即升序还是降序。
     
  • getValue: function(/*item*/item, /*attribute-name-string*/attribute, /*value?*/ defaultValue)

    用于获取某个给定的数据项的某个属性值,如果该条数据不含有指定的属性,则返回一个指定的默认值。item参数为给定的数据项,attribute参数为指定的属性字段,defaultValue为可选参数。

    var value = dataStore.getValue(item, 'name', 'no name'); 
  • getAttributes: function(/* item */ item)

    获取给定数据项的所有属性字段,返回值为一个数组。

Write

Dojo.data.Wirte接口主要提供了数据的更新功能API,包括创建、删除、更新数据。同 Read 接口类似,Write API 的设计目标也是屏蔽底层数据存储格式的差异,为用户提供统一的数据访问 API。借助这些 API,用户可以专注于业务层面的逻辑实现,而无需花费太多精力去关注底层数据的存储格式。

  • newItem: function(/*Object?*/ keywordArgs, /*Object?*/ parentInfo)

    在DataStore中新创建一个数据项。第一个参数为一个键值对对象,用于设定新创建的数据项,第二个参数为可选参数,当用户想将新创建的数据项作为某个已存在的数据项的子,则可以通过这个参数进行设定。具体应用请参照下面的小示例:

    var euItem = {"id": "EU", "name":"Europe", "type":"continent", "children": [] }
    // 新建数据项
    dataStore.newItem(euItem);
    // 新建子数据项
    dataStore.newItem({"id": "GM", "name":"Germany", "type":"country"}, {parent: euItem, attribute: "children"});
  • deleteItem: function(/*item*/ item)

    在DataStore中删除指定的数据项。

  • setValue: function(/*item*/ item, /*string*/ attribute, /*almost anything*/value)

    更新某条给定数据项的某个属性值。

Notification

当DataStore中有数据更新时,相应的Notification中定义的监听函数就会被调用。使用过Dojo的读者可 能都会注意到,在Widget中一般不会有new、delete等其他Javascript库控件中常见的API。这是因为Dojo data的设计是力求将数据层与表现层进行分割,对数据的操作都集中在数据层进行控制,而数据集的改变也能够自动的在应用控件上进行反映,这一功能就是当DataStore在进行数据更新操作时,通过Notification接口的通知作用实现的。

  • onNew: function(/*item*/ newItem, /*object?*/ parentInfo)

    当DataStore中创建新数据项操作成功后被自动调用。newItem参数就是新创建的数据项对象,parentInfo是可选参数,用于描述新创建数据项的父数据项。

  • onDelete: function(/*item*/ deletedItem)

    当DataStore中删除某项数据项后被自动调用。deletedItem参数就是被删除的数据项对象。

  • onSet: function(/*item*/ item, /*attribute-name-string*/ attribute, /*object | array*/ oldValue, /*object | array*/ newValue)

    在DataStore的某项数据项被更新后进行调用。四个参数分别为数据项对象,被更新数据项属性,该数据的原有值以及更新后的值。

Identify

很多数据源都会为数据提供唯一的标识符,Dojo.data.Identify接口则提供了基于唯一标识符进行数据获取定位的API支持。

  • fetchItemByIdentity: function(/*object*/ keywordArgs)

    同Read接口中的fetch方法类似,此方法也是一个异步方法,用户需要在参数对象中指定数据项获取后的回调处理函数。keywordArgs参数是一个键值对对象,主要需要包括两个属性,一个是要进行指定获取的数据项标识符identify,另一个则是回调处理函数onItem。在指定identify的数据项获取成功后,onItem回调函数则会被自动调用,以处理后续操作。

     
  • getIdentity: function(/*item */ item)

    此方法用于获取给定数据项的标识符。

DataStore应用

一般来说,Dijit中的各个小部件都提供了对DataStore的支持,当我们在使用某个Widget来进行数据展现时,通常我们只需要根据数据源的格式类型来选择好DataStore,然后在Widget声明中对DataStore进行指定就可以了。下面我们就通过DataGrid及ComboBox作为数据展现UI,基于不同的数据格式为它们设置不同的DataStore。

以下是一份JSON数据:

 

在这里,我们采用比较简单的dojo.data.ItemFileReadStore:

var jsOnStore= new dojo.data.ItemFileReadStore({data: data}); 

ItemFileReadStore比较适合于处理数据量较小的数据源,数据源可以是一个JSON文件或者象本例一样直接指定到客户端内存中的一组数据。当你使用更加大型的JSON数据集时,可以使用JsonRestStore,采用Rest服务来进行数据提供。

接下来,我们来声明一个DataGrid。在这里DataStore是通过”store”属性进行设置的。

 

生成的DataGrid如下图所示:

由于Dojo中对数据展现层与数据中间层的松耦合,同样一份数据源可以在不进行任何处理的情况下为多个Widget提供数据,而且由于数据的过滤、排序、分页都是根据数据获取请求按需返回的,使用相同 DataStore的多个Widget间也不会产生冲突。下面我们就以同样的DataStore,为一个dijit.form.ComboBox提供数据:

 

在很多实际应用中,可能会使用不同的数据源,下面,我们采用不同的数据格式,以XmlStore来替换ItemFileReadStore。首先将JSON数据转换为XML数据格式:

 

XmlStore是一个客户端的数据存储器,用于读取XML数据源。它由Dojo官方提供并包含在DojoX子项目中。XmlStore为基本的XML数据(一种常用的数据交换格式)提供读/写接口。XmlStore可以用于一般的XML文档,因此非常有用。存储器的设计是你可以通过覆盖其部分方法来自定义读/写数据的行为。下面的示例给出了如何创建XmlStore并将其应用到Grid及ComboBox中:

 

我们几乎不需要修改关于Grid和ComboBox的任何代码,就能让它们继续工作。唯一需要做的改动,就是声明一个数据源,并将它设置为grid的输入。我们不需要操心任何关于数据获取、解析、以及管理的事情,数据存储器的API做了所有的工作。

可以看出,作为数据中间层,Dojo.data通过优秀的API设计充分达成了数据展现层与数据管理层之间的松耦合,同时统一的数据访问接口使得对多种数据格式的应用以及程序移植都带来了相当大的便利性。

 


推荐阅读
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 企业数据应用挑战及元数据管理的重要性
    本文主要介绍了企业在日常经营管理过程中面临的数据应用挑战,包括数据找不到、数据读不懂、数据不可信等问题。针对这些挑战,通过元数据管理可以实现数据的可见、可懂、可用,帮助业务快速获取所需数据。文章提出了“灵魂”三问——元数据是什么、有什么用、又该怎么管,强调了元数据管理在企业数据治理中的基础和前提作用。 ... [详细]
author-avatar
凤凰花开清风自来_406
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有