API低代码平台介绍3-异构数据源的数据查询功能
异构数据源的数据查询功能
在上一篇文章中我们通过API平台定义了一个最基本的数据查询接口,本篇文章我们将上升难度,在原有接口的基础上,实现在MySQL数据库和Oracle数据库同时进行数据查询。
什么场景会需要同时对异构数据源进行查询?接着上篇文章的例子,比如您有一个老的业务系统是基于Oracle数据库开发的,后来系统升级,新业务系统是基于MySQL数据库开发的,由于种种原因,老系统的数据尚未迁移到新系统(或者过渡阶段新老系统可能还在同步运行,例如住建局的网签备案系统,老楼盘可能继续在老系统签订合同,新楼盘则在新系统签订合同),但我们又不得不确保另一个公司开发的预售资金监管系统能通过咱们的一个API接口查询到所有的买卖合同信息。下面来看看我们的API平台是如何轻松实现这一需求的。
1.测试数据准备
上篇文章我们已经准备了一个MySQL测试库business_system,我们把它当成新网签备案系统的数据库,那么这里我们再准备一个Oracle的测试库business_system_old来当成老网签备案系统的数据库,其中包括与business_system类似的三张表(为了区分,我这里故意把表名称和表结构设计得不一样):
2.1 幢表(db_buildings)
表结构如下:
幢表准备了两条数据:
2.2 户表(db_houses)
户表通过"building_id"外键字段与db_buildings表关联,表明这套房子属于哪个楼幢,表结构如下:
户表准备了两条数据:
2.3 交易者表(db_contracts)
交易者表记录了谁购买了哪一套房子(通过户house_id号关联户表),以及买卖合同编号等信息,表结构如下:
交易者表中保存了两个合同,其中的CL20231101000001合同有两个卖方(卖方A、卖方B)、两个买方(买方C、买方D);CL20231101000002合同有一个卖方(卖方E)和一个买方(买方F),数据如下:
2.4 接口需求
让预售资金监管系统以买卖合同号作为入参,使用GET请求查询该合同在网签备案系统对应的楼栋基本信息、户基本信息、卖方基本信息、买方基本信息,并且同时查询新老系统,要求接口响应如下json格式的业务数据:
{"ywbh": "业务编号","htbh": "合同编号","building": {"bdcdyh": "幢登记单元代码/不动产单元号","zl": "幢坐落"},"houses": [{"bdcdyh": "户登记单元代码/不动产单元号","fwbm": "房屋编码","szqsc": "所在起始层","szzzc": "所在终止层","shbw": "室号部位","fwzl": "房屋坐落","jzjg": "建筑结构","jzjgbm": "建筑结构编码","fwyt": "房屋用途","fwytbm": "房屋用途编码","jzmj": "建筑面积"}],"sellers": [{"jyzqc": "交易者全称","jyzzjmc": "交易者证件名称","jyzzjhm": "交易者证件号码","jyzxz": "交易者性质"}],"buyers": [{"jyzqc": "交易者全称","jyzzjmc": "交易者证件名称","jyzzjhm": "交易者证件号码","jyzxz": "交易者性质"}]
}
其中building用来装载幢基本信息,houses用来装载户基本信息,sellers用来装载卖方信息,buyers用来装载买方信息。
3.开始定义接口
3.1 新增OAuth客户端
我们把老网签备案系统作为客户端添加到API平台中,点击主界面的[OAuth客户端]菜单->点击[新增],填写如下字段:
点击保存即可,字段含义在上篇文章解释过,这里不再重复说明。
接下来,我们只需要在上篇文章定义的接口的基础上新增一个分享(即新增一个执行策略)即可。
3.2 新增一个分享
先在路由设置列表页面找到我们之前定义的路由,然后点击路由的[分享设置]-[新增],填写以下字段:
字段含义在上篇文章介绍过了,这里不再赘述。
注意分享编码不要和之前那个分享设置的编码重复(同一个路由下不同的分享设置必须要有不同的分享编码),分享名称根据实际情况填写即可;然后填写咱们Oracle数据库的连接信息,其它字段暂时用不上依然使用默认值,填写完成后点击保存即可。保存后,您将看到以下界面:
先选中刚才添加的分享设置,点击"数据库连接测试",看看我们填写的Oracle数据库连接信息是否正确,如图:
如果数据库连接成功,那么我们就可以在这个分享设置下编写sql语句了。
3.3 编写sql组装业务数据
点击分享设置的[数据定义],如图:
sql定义的过程可以完全参照上篇文章的过程,针对Oracle实际的库结构编写sql语句即可。
首先,我们把json报文的根节点字段查询出来,sql如下:
select distinct ywbh,contract_number as htbh from db_contracts j where j.contract_number = request~htbh~
如图:
接下来我们组装json中building(幢)节点的数据。点击点击分享设置的[数据定义]->[新增]
填写如下sql语句:
SELECT DISTINCT z.bdcdyh, z.location as zlFROM db_buildings zJOIN db_houses h ON h.building_id = z.idJOIN db_contracts jyz ON h.id = jyz.house_idAND jyz.ywbh = parent~ywbh~
如图:
接下来我们组装json中houses(户)节点的数据。点击点击分享设置的[数据定义]->[新增]
填写如下sql语句:
SELECT DISTINCTh.bdcdyh,h.fwbm,h.start_floor AS szqsc,h.end_floor AS szzzc,h.house_number AS shbw,h.location AS fwzl,h.structure AS jzjg,h.plan_use AS fwyt,h.area
FROMdb_houses hJOIN db_contracts jyz ON h.id = jyz.house_id AND jyz.ywbh = parent~ywbh~
如图:
接下来我们组装json中sellers(卖方)节点的数据。点击点击分享设置的[数据定义]->[新增]
填写如下sql语句:
SELECTj.trader_name AS jyzqc,j.trader_zjmc AS jyzzjmc,j.trader_zjhm AS jyzzjhm,j.trader_xz AS jyzxz
FROMdb_contracts j
WHEREj.ywbh = parent~ywbh~ AND j.trader_lb = '卖方'
如图:
接下来我们组装json中buyers(买方)节点的数据。点击点击分享设置的[数据定义]->[新增]
填写如下sql语句:
SELECTj.trader_name AS jyzqc,j.trader_zjmc AS jyzzjmc,j.trader_zjhm AS jyzzjhm,j.trader_xz AS jyzxz
FROMdb_contracts j
WHEREj.ywbh = parent~ywbh~ AND j.trader_lb = '买方'
如图:
到此为止,我们所有的sql都添加好了,数据定义列表截图如下:
4.在线测试接口
回到路由设置的列表页,找到我们刚才的路由,点击[打开文档],如图所示:
点击后可以看到API平台为我们自动生成的在线文档,如图:
我们先填写入参值:YS20231203000001(新网签备案系统的合同编号),点击[试一下],接口调用该接口,如图:
可以看到API平台为这个接口自动生成的接口地址与上篇文章相比没有任何变化,依然是"http://127.0.0.1:8080/adi/bitapi/queryMmhtJbxx",其中的adi和bitapi是固定路径,queryMmhtJbxx则是我们自定义的路由编码;响应报文如下:
{"type": "success","data": {"multiThreadResponses": [{"ywbh": "20231203000001","htbh": "YS20231203000001","building": {"bdcdyh": "110108001001GB00001F0001","zl": "北京市海淀区曙光中路曙光花园智业园1幢"},"houses": [{"bdcdyh": "110108001001GB00001F00010003","fwbm": "fbm0003","szqsc": 1,"szzzc": 1,"shbw": "103","fwzl": "北京市海淀区曙光中路曙光花园智业园1幢B座1-103","jzjg": "钢结构","fwyt": "住宅","jzmj": 183}],"sellers": [{"jyzqc": "张三","jyzzjmc": "居民身份证","jyzzjhm": "510121100909137101","jyzxz": "外省市个人"},{"jyzqc": "李四","jyzzjmc": "军官证","jyzzjhm": "wj0001","jyzxz": "军人"}],"buyers": [{"jyzqc": "王五","jyzzjmc": "户口簿","jyzzjhm": "522121100909137102","jyzxz": "本市城镇居民"},{"jyzqc": "赵六","jyzzjmc": "港澳台身份证","jyzzjhm": "gat0001","jyzxz": "台湾同胞"}]},{}]},"uuid": "4302af,18db3e"
}
其中的type、data、uuid依然是API平台响应的固定参数,观察报文,会发现和上篇文章只有一个分享设置时的响应报文有所区别:
首先,业务数据最外层多了一个multiThreadResponses节点,数据类型是jsonArray,它表示多线程响应,这是因为我们这个路由下有多个分享设置,且这些分享设置被多线程并行执行了,multiThreadResponses装载了所有分享设置响应的业务数据,这个数组的第二个元素是个空对象({}),表示其中一个分享设置没有查到任何数据。
其次,uuid变成了两个值(4302af,18db3e),这两个值各自对应了一个分享设置的请求唯一编码(只截取了前6位)。
让我们查询最新的分享日志看看,如图:
通过分享日志可以看到,两个分享设置都被成功执行了。
接下来,我们在入参输入一个老系统的合同编号CL20231101000001,并点击试一下,如图:
响应报文如下:
{"type": "success","data": {"multiThreadResponses": [{},{"ywbh": "20231101000001","htbh": "CL20231101000001","building": {"bdcdyh": "110108001001GB00001F0003","zl": "北京市海淀区曙光中路曙光花园智业园3幢"},"houses": [{"bdcdyh": "110108001001GB00001F00030001","fwbm": "fbmF00030001","szqsc": 1,"szzzc": 1,"shbw": "101","fwzl": "北京市海淀区曙光中路曙光花园智业园3幢B座1-101","jzjg": "钢结构","fwyt": "住宅","area": 100}],"sellers": [{"jyzqc": "卖方A","jyzzjmc": "居民身份证","jyzzjhm": "510121100909137105","jyzxz": "本市城镇居民"},{"jyzqc": "卖方B","jyzzjmc": "居民身份证","jyzzjhm": "510121100909137106","jyzxz": "本市城镇居民"}],"buyers": [{"jyzqc": "买方C","jyzzjmc": "居民身份证","jyzzjhm": "510121100909137107","jyzxz": "本市城镇居民"},{"jyzqc": "买方D","jyzzjmc": "居民身份证","jyzzjhm": "510121100909137108","jyzxz": "本市城镇居民"}]}]},"uuid": "ac8553,fd8391"
}
可以看到,老系统的合同信息也被查询出来了,新系统的查询结果是空对象({})。
到这里,同时查询新老系统的需求已经实现了,但您可能会有疑问:多个分享设置的时候,响应报文的格式和之前发生了变化,会增加接口调用者解析报文的难度,这该怎么办呢?当然有办法处理,继续往下看。
4.调整相应报文的格式-ADI响应_转换JS
打开路由设置的响应,会看到一个字段:ADI响应_转换JS,如图:
在这个字段中,我们可以编写一个JavaScript方法(里面还可以有java语法),实现对data节点报文格式的任意转换:
function formatterJson(oldJson,newJson){ if(oldJson.multiThreadResponses) { //如果是多线程返回结果for (var i = 0; i <oldJson.multiThreadResponses.length; i++){ //变量多线程结果if(oldJson.multiThreadResponses[i].size() > 0) { //如果有结果,即不是空对象{}newJson = oldJson.multiThreadResponses[i]; //把结果赋值给newJsonbreak;}}return newJson; //有multiThreadResponses,则返回newJson} return oldJson; //没有multiThreadResponses节点,可能只启用了一个分享设置,就直接返回
}
注意: 方法名formatterJson是固定写法,不能变;oldJson是格式转换前data节点下的原始json数据;newJson是空的json对象(即{}),一般用来接收格式转换后的json数据。
如图:
点击保存即可。
接下来,我们再调用接口,看看响应报文:
{"type": "success","data": {"ywbh": "20231101000001","htbh": "CL20231101000001","building": {"bdcdyh": "110108001001GB00001F0003","zl": "北京市海淀区曙光中路曙光花园智业园3幢"},"houses": [{"bdcdyh": "110108001001GB00001F00030001","fwbm": "fbmF00030001","szqsc": 1,"szzzc": 1,"shbw": "101","fwzl": "北京市海淀区曙光中路曙光花园智业园3幢B座1-101","jzjg": "钢结构","fwyt": "住宅","area": 100}],"sellers": [{"jyzqc": "卖方A","jyzzjmc": "居民身份证","jyzzjhm": "510121100909137105","jyzxz": "本市城镇居民"},{"jyzqc": "卖方B","jyzzjmc": "居民身份证","jyzzjhm": "510121100909137106","jyzxz": "本市城镇居民"}],"buyers": [{"jyzqc": "买方C","jyzzjmc": "居民身份证","jyzzjhm": "510121100909137107","jyzxz": "本市城镇居民"},{"jyzqc": "买方D","jyzzjmc": "居民身份证","jyzzjhm": "510121100909137108","jyzxz": "本市城镇居民"}]},"uuid": "d84de0,b0d3a1"
}
响应的业务数据格式就和之前一样了,问题被解决。
API平台的js执行能力使得平台功能更加灵活,有时候我们可能想合并多个分享设置的执行结果(比如要查询某个人名下的房产,可能需要调用各区县的业务系统得到查询结果),通过js格式转换也是很容易实现的。
到这里,相信大家已经知道如何同时对多个数据源进行查询了,后续我将继续介绍ADI平台其它的重要功能,谢谢您的阅读!
相关文章:

API低代码平台介绍3-异构数据源的数据查询功能
异构数据源的数据查询功能 在上一篇文章中我们通过API平台定义了一个最基本的数据查询接口,本篇文章我们将上升难度,在原有接口的基础上,实现在MySQL数据库和Oracle数据库同时进行数据查询。 什么场景会需要同时对异构数据源进行查询&…...

【Linux】-网络请求和下载、端口[6]
目录 一、网络请求和下载 1、ping命令 2、wget命令 3、curl命令 二、端口 1、虚拟端口 2、查看端口占用 一、网络请求和下载 1、ping命令 可以通过ping命令,检查指定的网络服务器是否可联通状态 语法:ping [ -c num ] ip或主机名 选项&…...

Github2024-05-10开日报 Top10
根据Github Trendings的统计,今日(2024-05-10统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目4TypeScript项目4JavaScript项目1Lua项目1C项目1Rust项目1Dart项目1 RustDesk: 用Rust编写的开源远…...

2016-2021年全国范围的2.5m分辨率的建筑屋顶数据
一、论文介绍 摘要:大规模且多年的建筑屋顶面积(BRA)地图对于解决政策决策和可持续发展至关重要。此外,作为人类活动的细粒度指标,BRA可以为城市规划和能源模型提供帮助,为人类福祉带来好处。然而…...

Gitea 上传用户签名
在 Gitea 的用户管理部分,有一个 SSH 和 GPG 的选项。 单击这个选项,可以在选项上添加 Key。 Key 的来源 如是 Windows 的用户,可以选择 Kleopatra 这个软件。 通过这个软件生成的 Key 的界面中有一个导出功能。 单击这个导出,…...

【原创】springboot+mysql物资库存管理系统设计与实现
个人主页:程序猿小小杨 个人简介:从事开发多年,Java、Php、Python、前端开发均有涉猎 博客内容:Java项目实战、项目演示、技术分享 文末有作者名片,希望和大家一起共同进步,你只管努力,剩下的交…...

vulnhub靶场之FunBox-5
一.环境搭建 1.靶场描述 Lets separate the script-kids from script-teenies.Hint: The first impression is not always the right one!If you need hints, call me on twitter: 0815R2d2 Have fun...This works better with VirtualBox rather than VMwareThis works bett…...

1分钟搞定Pandas DataFrame创建与索引
1.DataFrame介绍 DataFrame 是一个【表格型】的数据结构,可以看作是【由Series组成的字典】(共用同一个索引)。DataFrame 由按一定顺序排列的多列数据组成。设计初衷是将 Series 的使用场景从一维扩展到多维。DataFrame 既有行索引ÿ…...

【贪心算法】哈夫曼编码Python实现
文章目录 [toc]哈夫曼编码不同编码方式对比前缀码构造哈夫曼编码哈夫曼算法的正确性贪心选择性质证明 最优子结构性质证明 总结 Python实现时间复杂性 哈夫曼编码 哈夫曼编码是广泛用于数据文件压缩的十分有效的编码方法,其压缩率通常为 20 % 20\% 20%到 90 % 90\%…...

【RAG 博客】RAG 应用中的 Routing
Blog:Routing in RAG-Driven Applications ⭐⭐⭐⭐ 根据用户的查询意图,在 RAG 程序内部使用 “Routing the control flow” 可以帮助我们构建更实用强大的 RAG 程序。路由模块的关键实现就是一个 Router,它根据 user query 的查询意图&…...

鸿蒙ArkUI:【编程范式:命令式->声明式】
命令式 简单讲就是需要开发用代码一步一步进行布局,这个过程需要开发全程参与。 开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 Objective-C ObjectiveC 复制代码 UIView *cardView …...

【练习2】
1.汽水瓶 ps:注意涉及多个输入,我就说怎么老不对,无语~ #include <cmath> #include <iostream> using namespace std;int main() {int n;int num,flag,kp,temp;while (cin>>n) {flag1;num0;temp0;kpn;while (flag1) {if(kp<2){if(…...

oracle 新_多种块大小的支持9i
oracle 新_多种块大小的支持 conn sys/sys as sysdba SHOW PARAMETER CACHE ALTER SYSTEM SET DB_CACHE_SIZE16M; ALTER SYSTEM SET DB_4K_CACHE_SIZE8M; CREATE TABLESPACE K4 DATAFILE F:\ORACLE\ORADATA\ZL9\K4.DBF SIZE 2M BLOCKSIZE 4K; CREATE TABLE SCOTT.A1 TABLESP…...

Collections工具类
类java.util.Collections提供了对Set、List、Map进行排序、填充、查找元素的辅助方法。 方法名说明void sort(List)对List容器内的元素排序,排序规则是升序void shuffle(List)对List容器内的元素进行随机排列void reverse(List)对List容器内的元素进行逆序排列void…...

java-函数式编程-jdk
背景 函数式接口很简单,但是不是每一个函数式接口都需要我们自己来写jdk 根据 有无参数,有无返回值,参数的个数和类型,返回值的类型 提前定义了一些通用的函数式接口 IntPredicate 参数:有一个,类型是int类…...

qiankun实现微前端,vue3为主应用,分别引入vue2和vue3微应用
1、vue3主应用配置 1、安装 qiankun yarn add qiankun # 或者 npm i qiankun -S2、在主应用中注册微应用 import { registerMicroApps, start } from "qiankun" const apps [{ name: vue2App, // 应用名称 xs_yiqing_vue2entry: //localhost:8080, // vue 应用…...

写了 1000 条 Prompt 之后,我总结出了这 9 个框架【建议收藏】
如果你对于写 Prompt 有点无从下手,那么,本文将为你带来 9 个快速编写 Prompt 的框架,你可以根据自己的需求,选择任意一个框架,填入指定的内容,即可以得到一段高效的 Prompt,让 LLM 给你准确满意…...

事件代理 浅谈
事件代理是一种将事件处理委托给父元素或祖先元素来管理的技术。当子元素触发特定事件时,该事件不会直接在子元素上进行处理,而是会冒泡到父元素或祖先元素,并在那里进行处理。这样做的好处是可以减少事件处理函数的数量,提高性能…...

一对多在线教育系统,疫情后,在线教育有哪些变革?
疫情期间,全面开展的在线教育经历了从不适应到认可投入并常态化的发展过程。如何发挥在线教学优势,深度融合线上与线下教育,将在线教育作为育人方式变革动力,提升育人服务水平,是复学复课后学校教育教学面临的关键问题…...

RabbitMQ(安装配置以及与SpringBoot整合)
文章目录 1.基本介绍2.Linux下安装配置RabbitMQ1.安装erlang环境1.将文件上传到/opt目录下2.进入/opt目录下,然后安装 2.安装RabbitMQ1.进入/opt目录,安装所需依赖2.安装MQ 3.基本配置1.启动MQ2.查看MQ状态3.安装web管理插件4.安装web管理插件超时的解决…...

JUC下的BlockingQueue详解
BlockingQueue是Java并发包(java.util.concurrent)中提供的一个接口,它扩展了Queue接口,增加了阻塞功能。这意味着当队列满时尝试入队操作,或者队列空时尝试出队操作,线程会进入等待状态,直到队列状态允许操作继续。这…...

ChatGPT理论分析
ChatGPT "ChatGPT"是一个基于GPT(Generative Pre-trained Transformer)架构的对话系统。GPT 是一个由OpenAI 开发的自然语言处理(NLP)模型,它使用深度学习来生成文本。以下是对ChatGPT进行理论分析的几个主…...

算法提高之魔板
算法提高之魔板 核心思想:最短路模型 将所有状态存入队列 更新步数 同时记录前驱状态 #include <iostream>#include <cstring>#include <algorithm>#include <unordered_map>#include <queue>using namespace std;string start&qu…...

服务器内存占用不足会怎么样,解决方案
在当今数据驱动的时代,服务器对于我们的工作和生活起着举足轻重的作用。而在众多影响服务器性能的关键因素当中,内存扮演着极其重要的角色。 服务器内存,也称RAM(Random Access Memory),是服务器核心硬件部…...

elasticsearch文档读写原理大致分析一下
文档写简介 客户端通过hash选择一个node发送请求,专业术语叫做协调节点 协调节点会对document进行路由,将请求转发给对应的primary shard primary shard在处理完数据后,会将document 同步到所有replica shard 协调节点将处理结果返回给…...

1 开发环境
开发环境(platformio python arduino框架)的搭建可以参考b站upESP32超详细教程-使用VSCode(基于Arduino框架)哔哩哔哩bilibili 这里推荐离线安装esp32库文件,要不然要等很久(b站教程很多) 搭…...

云视频,也称为视频云服务,是一种基于云计算技术理念的视频流媒体服务
云视频,也称为视频云服务,是一种基于云计算技术理念的视频流媒体服务。它基于云计算商业模式,为视频网络平台服务提供强大的支持。在云平台上,所有的视频供应商、代理商、策划服务商、制作商、行业协会、管理机构、行业媒体和法律…...

[Vision Board创客营]--使用openmv识别阿尼亚
文章目录 [Vision Board创客营]使用openmv识别阿尼亚介绍环境搭建训练模型上传图片生成模型 使用结语 [Vision Board创客营]使用openmv识别阿尼亚 🚀🚀五一和女朋友去看了《间谍过家家 代号:白》,入坑二刺螈(QQ头像也换…...

【Linux:lesson1】的基本指令
🎁个人主页:我们的五年 🔍系列专栏:Linux课程学习 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 🚗打开Xshell,登陆root…...

20240511日记
今天工作内容: 1.二期2号机EAP测试 2.二期开门机器暂停(停轴,停流水线电机),关闭门后继续功能测试 3.针点位偏移还需要调整,未进行大批量验证是否偏移(S3模板点位测试,两台机各焊…...