groovy将JDBC中oracle存储过程游标转换为多层json

        

        本例是我工作中的一些实操例子,亦是我工作日志,记录在此,既可作为我自己的总结,也可以此分享给同行借鉴。

        入参是字符串格式的xml,目的是解析xml节点值,作为数据库检索where条件,检索出数据库记录,利用四个游标返回四个数据集,然后用groovy脚本将四个游标数据集解析成json出参中对应的四个节点值。出参json有两层结构,第一层是"data": [],第二层的"checkinfo": [],"bacinfo": [],"tesinfo": []节点是在"data": []层下面。

        因为我用的oracle是11g的。所以需要通过自建xml解析函数配合groovy脚本来转换成json,貌似oracle 12g后的版本才有JSON_VALUE函数处理json格式数据。但我没有研究过。

第一步,创建解析xml的函数脚本如下(因为本例调用存储过程的入参是xml格式的,所以需要借助这个函数来解析下入参,取到xml对应的节点值

CREATE OR REPLACE FUNCTION your_function(as_xml_string in clob, as_xml_mark in varchar2)
    return varchar2 Is
    vs_bmark  varchar2(64);
    vs_emark  varchar2(64);
    vs_source varchar2(10240);
    vs_xmlval varchar2(10240);
    vi_bpos   integer;
    vi_epos   integer;
  
  begin
    vs_bmark  := '<' || lower(as_xml_mark) || '>';
    vs_emark  := '</' || lower(as_xml_mark) || '>';
    vs_source := lower(replace(replace(as_xml_string, '<![CDATA['), ']]>'));--有些xml是来自接口入参,入参会有'<![CDATA[',']]>'等字符,所以要替换掉
  
    vi_bpos := instr(vs_source, vs_bmark);
    vi_epos := instr(vs_source, vs_emark);
  
    if vi_bpos > 0 and vi_epos > 0 then
      vi_bpos   := vi_bpos + length(vs_bmark);
      vs_xmlval := substr(replace(replace(as_xml_string, '<![CDATA['),
                                  ']]>'),
                          vi_bpos,
                          vi_epos - vi_bpos);
    end if;
	
    return vs_xmlval;
  end;

第二步,创建oracle存储过程,放在本文附件,脚本代码略多,为了不影响篇幅,此处略

第三步,JDBC调用存储过程语句如下,Jdbc调用存储过程的语句()里IN代表入参,OUT代表出参,本例入参data是从程序前端传进来的字符串xml,参考下文xml入参示例。

Call your_procedure ({IN#VARCHAR2#data},{OUT#VARCHAR2#fbusinesstype},{OUT#VARCHAR2#fmsgid},{OUT#VARCHAR2#fcreationtime},{OUT#VARCHAR2#fcode},{OUT#VARCHAR2#fresultmessage},{OUT#CURSOR#data},{OUT#CURSOR#checkinfo},{OUT#CURSOR#bacinfo},{OUT#CURSOR#tesinfo})

第四步,创建groovy脚本如下,Groovy脚本处理游标出参,groovy出来的其实是map格式,但map转json或者map转xml有很多java的工具包可用。这里不赘述。本例用了一些金蝶云的包,公司是基于Apache Camel,再把groovy集成进去,构建消息引擎中间件。每家公司都可能不一样,这里亦不赘述。

package com.kingdeehit.cloud.integration;//金蝶云包
import com.kingdeehit.cloud.core.exception.CloudBaseException; //金蝶云包
import com.kingdeehit.cloud.integration.service.IGroovyPlugin; //金蝶云包
import org.apache.camel.Exchange;
import java.util.*;

public class Groovy extends IGroovyPlugin {
    @Override
    public void process(Exchange exchange) {

        HashMap body = (HashMap) exchange.getIn().getBody();
		//获取循环外内容
		String fbusinesstype = body.get("fbusinesstype");
		String fcreationtime = body.get("fcreationtime");
		String fmsgid = body.get("fmsgid");
		String fresultmessage = body.get("fresultmessage");
		String fcode = body.get("fcode");
		//获取循环内容
        ArrayList DataBody = (ArrayList)body.get("data");
		ArrayList CheckinfoBody = (ArrayList)body.get("checkinfo");
		ArrayList BacinfoBody = (ArrayList)body.get("bacinfo");
		ArrayList TesinfoBody = (ArrayList)body.get("tesinfo");
		//定义新body
		HashMap newbody = new HashMap();
		ArrayList newDataBody = new ArrayList();
		for(int i=0; i< DataBody.size(); i++)//第一层"data": []节点循环取值
        {
			HashMap tempDataMap = (HashMap) DataBody.get(i);
            String tempDataId = tempDataMap.get("freportno").toString();
			ArrayList CheckDone = new ArrayList();
			ArrayList BacDone = new ArrayList();
			ArrayList TesDone = new ArrayList();
			for(int j = 0; j< CheckinfoBody.size();j++)//第二层"checkinfo": []节点循环取值
            {
				HashMap tempCheckMap = (HashMap) CheckinfoBody.get(j);
				String tempCheckId = tempCheckMap.get("freportno").toString();
				if(tempDataId == tempCheckId)
				{
					CheckDone.add(tempCheckMap);
				}
			};
			for(int k = 0; k< BacinfoBody.size();k++)//第二层"bacinfo": []节点循环取值
            {
				HashMap tempBacMap = (HashMap) CheckinfoBody.get(k);
				String tempBacId = tempBacMap.get("freportno").toString();
				if(tempDataId == tempBacId)
				{
					BacDone.add(tempBacMap);
				}
			};
			for(int l = 0; l< TesinfoBody.size();l++)//第二层"tesinfo": []节点循环取值
            {
				HashMap tempTesMap = (HashMap) CheckinfoBody.get(l);
				String tempTesId = tempTesMap.get("freportno").toString();
				if(tempDataId == tempTesId)
				{
					TesDone.add(tempTesMap);
				}
			};
			tempDataMap.put("checkinfo", CheckDone);
			tempDataMap.put("bacinfo", BacDone);
			tempDataMap.put("tesinfo", TesDone);
			newDataBody.add(tempDataMap);
		};
		//拼装新body
		newbody.put("fbusinesstype",fbusinesstype);
		newbody.put("fcreationtime",fcreationtime);
		newbody.put("fmsgid",fmsgid);
		newbody.put("fresultmessage",fresultmessage);
		newbody.put("fcode",fcode);
		newbody.put("data",newDataBody);
        exchange.getIn().setBody(newbody);
    }
}

xml入参示例如下:

{
    "data": {
        "fmsgid": "*******",
        "fsource": "",
        "freporton": "",
        "freporttimelow": "",
        "freporttimehigh": "",
        "finpatientno": "",
        "fvisitordno": "",
        "fvisittypecode": "",
        "fvisittype": "",
        "fwardno": "",
        "fdeptno": "",
        "fpatientid": "1************0",
        "fidcard": ""
    }
}

json出参示例:在本文附件,此处略。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值