人们常说,计划赶不上变化。同样的,在项目中,使用的数据也是在不断变化的,尤其是属性信息的改变。就比如说,地图上的地物,它的空间信息在比较长的时间内,都不会发生变化,他的属性信息在初期不完整或者与后来的信息不符合,这时就可以使用SuperMap iClient for JavaScript 的关联查询。
那如何进行关联查询呢?不急,我们先在iClient for JavaScript中去找找与关联查询相关的类或接口。
首先,JavaScript客户端内,查询从分布的服务类别可区分为两类,一是基于地图服务的查询,一种是基于数据服务的查询;按照查询参数的不同有可分为SQL,几何,范围,距离,缓冲区查询。这里主要给大家分享一下基于地图服务的查询。
基于地图服务的查询参数基类为SuperMap.REST.QueryParameters,下图展示了该类的属性接口
通过上面的图表,我们能够直观地了解到每个属性参数所代表的意义,这里就不一一讲解了,主要说一下红框所标示的queryParams所对应的查询过滤条件参数类–SuperMap.REST.FilterParameter。首先,我们同样通过一张图表来看看该类包含了哪些属性接口
没错,关联查询所要用到的接口,就出现在这里了。那我们就来好好研究研究JoinItem和LinkItem吧。
待查询数据集与外部表属于同一数据源
SuperMap.REST.JoinItem,连接信息类。 该类用于定义矢量数据集与外部表的连接信息。 外部表可以为另一个矢量数据集(其中纯属性数据集中没有空间几何信息)所对应的 DBMS(Database Management System,数据库管理系统)表, 也可以是用户自建的业务表。需要注意的是,矢量数据集与外部表必须属于同一数据源。 用于连接两个表的字段的名称不一定相同,但类型必须一致。即同为整型,或同为字符型等。
这样看这张图表,可能会觉得有的繁琐,那我们就直接通过下面的一段代码,直观的感受下JoinItem的用法, 代码所用到的数据是iserver自带的map-world。
1 function queryBySQL() { 2 vectorLayer.removeAllFeatures(); 3 //设置外部表的连接信息 4 var joinitem=new SuperMap.REST.JoinItem({ 5 //外部表的名称 6 foreignTableName: "Capitals", 7 //建立查询数据与外部表之间的连接字段 8 joinFilter: "Capitals.SmID = Countries.SmID", 9 //有两种连接类型 一是左连接("LEFTJOIN")二是等值连接("INNERJOIN") 10 joinType: "LEFTJOIN" 11 }); 12 var queryParam, queryBySQLParams, queryBySQLService; 13 queryParam = new SuperMap.REST.FilterParameter({ 14 //待查询图层名 15 name: "Countries@World.1", 16 attributeFilter: "Countries.SmID=5", 17 joinItems:[joinitem] 18 //可设置返回的字段数组 这里不进行设置 即返回所有属性字段 19 //fields:[] 20 }); 21 queryBySQLParams = new SuperMap.REST.QueryBySQLParameters({ 22 queryParams: [queryParam] 23 }); 24 queryBySQLService = new SuperMap.REST.QueryBySQLService(url, { 25 eventListeners: { 26 "processCompleted": processCompleted, 27 "processFailed": processFailed}}); 28 queryBySQLService.processAsync(queryBySQLParams); 29 }
这里需要提醒大家一下,当外部表也是数据源内的矢量数据集时,不要混淆foreignTableName这个参数和查询参数queryParam内name这个属性的写法,foreignTableName即是数据集名,而非地图内所对应的图层名,因此上面的代码中,外部表为Capitals,而非Capitals@World.1。
查询成功后,返回的结果中的地物不仅有地物本身的属性信息,还包含外部表所包含的属性信息。
待查询数据集与外部表属于不同数据源
SuperMap.REST.LinkItem关联信息类,该类用于定义矢量数据集与外部表之间的关联信息。使用 LinkItem 的约束条件:空间数据和属性数据必须有关联条件,即主空间数据集与外部属性表之间存在关联字段。 主空间数据集:用来与外部表进行关联的数据集。下面两张图表为LinkItem所用到的参数信息。
同样的,我们直接通过代码来理解LinkItem这个类
1 function queryBySQL() { 2 // 设置关联的外部数据库信息,alias表示数据库别名 3 var dc = new SuperMap.REST.DatasourceConnectionInfo({ 4 dataBase: "RelQuery", 5 server: "192.168.168.39", 6 user: "sa", 7 password: "map", 8 driver: "SQL Server", 9 connect: true, 10 OpenLinkTable: false, 11 alias: "RelQuery", 12 engineType: SuperMap.REST.EngineType.SQLPLUS, 13 readOnly: false, 14 exclusive: false 15 }); 16 // 设置关联信息 17 var linkItem = new SuperMap.REST.LinkItem({ 18 datasourceConnectionInfo: dc, 19 foreignKeys: ["name"], 20 foreignTable: "Pop_2011", 21 linkFields: ["SmID as Pid","pop"], 22 name: "link", 23 primatryKeys: ["name"], 24 }); 25 // 设置查询参数,在查询参数中添加linkItem关联条件信息 26 var queryParam, queryBySQLParams, queryBySQLService; 27 queryParam = new SuperMap.REST.FilterParameter({ 28 name: "Province@RelQuery", 29 fields: ["SmID","name"], 30 attributeFilter: "SmID<7", 31 linkItems: [linkItem] 32 }), 33 queryBySQLParams = new SuperMap.REST.QueryBySQLParameters({ 34 queryParams: [queryParam] 35 }), 36 queryBySQLService = new SuperMap.REST.QueryBySQLService(url, { 37 eventListeners: { 38 "processCompleted": processCompleted, 39 "processFailed": processFailed 40 } 41 }); 42 queryBySQLService.processAsync(queryBySQLParams); 43 }
这里需要注意server以及driver这两个参数
除了使用linkItem关联查询不同数据源的数据,其实也可使用joinItem,这时,你可能会说,这和前面所介绍的joinItem必须在同一数据源内有冲突。然而并没有,使用joinItem时,是需要在待查询数据集所在的数据源内新建视图,故查询的是视图,而非其他数据源内的表。那么如何创建视图,可能很多朋友都已经知道了,这里以oracle数据库为例,给大家简要介绍一下。在sqlplus窗口,输入以下代码:
1 create or replace view link as //创建或替换一个名为link的视图 2 select * //查找的字段 3 from //外部表 4 where //查找条件
建立视图后,就可以直接使用joinItem进行关联查询,请看以下代码
1 var joinitem=new SuperMap.REST.JoinItem({ 2 foreignTableName: "LINK", //填写视图名 3 joinFilter: "LINK.SMID = SamplesP.SmID", //关联字段 4 joinType: "INNERJOIN" 5 });
到这里,你就已经学会如何使用SuperMap iClient for JavaScript 的关联查询了。赶快去你的项目中,实践一下吧。