java-blob类型(xml格式)与json对象/map互相转换

目录

1、前端显示(blob转json)

解释:从数据库-oracle取出该blob,进行blob转json;blob类型在数据库中以二进制字节流存储【BLOB(二进制大对象)是一个变长的二进制字符串,最长可达2,147,483,647个字符。与其他二进制类型一样,BLOB字符串与代码页无关。另外,BLOB字符串不包含字符数据。

BLOB以字节为单位给出长度,除非给出后缀K,M或G中的一个,分别与1024,1024 * 1024,1024 * 1024 * 1024的倍数相关。

注意:长度以字节为单位指定BLOB。】

(1)代码如下(借助BlobHelper工具类)

/**
fieldguid:主键id
col:列名
**/
public static Map<String,String> getFieldBlobToJson(String fieldguid,String col){
		Map<String,String> json=new HashMap<String,String>();
		try {
			InputStream field=BlobHelper.query(dataModel, "M_FIELDDEF", col, fieldguid);
			if(null==field) return json;
			String xmlStr  =BlobHelper.streamToString(field);
			Document ret=	DocumentHelper.parseText(xmlStr);//
			Element rootElement= ret.getRootElement();
			
			if("FAUTOFILLDEF".equals(col)) {
				json=getAutoFillData(rootElement);
			}
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return json;
	}
	private static Map<String,String> getAutoFillData(Element rootElement) {
		// TODO 自动生成的方法存根
		Map<String,String> map=new HashMap<String,String>();
		String defaultValue=getCDataOfElement(rootElement,"defaultValue");
		String createExpr=getCDataOfElement(rootElement,"createExpr");
		String calcExpr=getCDataOfElement(rootElement,"calcExpr");
		String calcExpr2=getCDataOfElement(rootElement,"calcExpr2");
		map.put("defaultValue", defaultValue);
		map.put("createExpr", createExpr);
		map.put("calcExpr", calcExpr);
		map.put("calcExpr2", calcExpr2);
		
		return map;
	}

	
	private static String getCDataOfElement(Element parentEl,String elLabel) {
		// TODO 自动生成的方法存根
		String res="";
		Element elLabelEl=parentEl.element(elLabel);
		@SuppressWarnings("rawtypes")
		List content=elLabelEl.content();
		for(Object o:content){
			if(o instanceof CDATA){
				CDATA cdata=(CDATA) o;
				res=cdata.getText();
			}
			
		}
		return res;
	}

调试结果:xmlStr值

<autoFillDef majorVer="1" minorVer="0"><defaultValue><![CDATA[主键]]></defaultValue><createExpr><![CDATA[geoToTable(null,null,null,null,null,null)]]></createExpr><calcExpr2><![CDATA[$model.B_SuperviseMsg.val("FGUID")]]></calcExpr2><calcExpr><![CDATA[string()now()]]></calcExpr></autoFillDef>

前端接收的值为json

{defaultValue:“主键”,createExpr:“geoToTable(null,null,null,null,null,null)”}

oracle中该blob字段存储内容为

<?xml version="1.0" encoding="gbk"?>
<autoFillDef majorVer="1" minorVer="0">
  <defaultValue><![CDATA[主键]]></defaultValue>
  <createExpr><![CDATA[invokeStaticMethod(null,null,null,null)]]></createExpr>
  <calcExpr><![CDATA[substring-before()]]></calcExpr>
  <calcExpr2><![CDATA[$model.B_SuperviseMsg.val("FGUID")]]></calcExpr2>
</autoFillDef>

2、后台保存(json转blob)

把前端的数据组装成json字符串,在后台存储到oracle,进行json转blob

(1)前端组装成json字符串

var jsonObj={};
		jsonObj.majorVer="1";
		jsonObj.minorVer="0";
		var domList=[];
		var xmlData=this.comp("xmlData");
		var cRow = xmlData.getCurrentRow();
		var cols=xmlData.getColumnIDs().split(",");
		for(var i=cols.length-1;i>-1;i--) {
			if(cols[i]&&cols[i]!="fieldguid") {//非主键
				var tempObj={};
				tempObj[cols[i]]=cRow.val(cols[i]);
				domList.push(tempObj);
				
			}
			
		}
		jsonObj.domList=domList;
		params.setString("fieldguid",self._params.fguid);
		params.setString("col",self._params.col);
		params.setString("lableName","autoFillDef");
		params.setString("jsonObj",JSON.stringify(jsonObj));

(2)调用后台方法
代码如下(借助BlobHelper工具类),获取k-v键名键值(用entrySet()转换)

public static void saveJsonToBlob(String fieldguid,String col,String lableName,String jsonObj){
		String domStr =null;
		if(null!=jsonObj){
			JSONObject obj = JSONObject.parseObject(jsonObj);
			
			Document document = DocumentHelper.createDocument();
			Element rootEl=  document.addElement(lableName);
			//fastjson解析方法
            for (Map.Entry<String, Object> entry : obj.entrySet()) {
                if(entry.getValue().toString().startsWith("[{")) {//key为json数组
                	if("FAUTOFILLDEF".equals(col)) {
        				addAutoFillDoms(rootEl, (JSONArray) entry.getValue());
        			}
                } else {
                	rootEl.addAttribute(entry.getKey(), (String) entry.getValue());
                }
            }
			domStr =rootEl.asXML();
		}
		System.out.println("domStr==="+domStr);
		InputStream stream = BlobHelper.strToStream(domStr);
		try {
			BlobHelper.update(dataModel, "M_FIELDDEF", col, null, fieldguid, null, stream);
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
	
	private static void addAutoFillDoms(Element rootEl, JSONArray domList) {
		// TODO 自动生成的方法存根
		if(domList.size()>0) {
			for(Iterator<Object> iterator=domList.iterator();iterator.hasNext();) {
				JSONObject json=(JSONObject) iterator.next();
				for(Map.Entry<String,Object> entry:json.entrySet()) {
					org.dom4j.Element el=rootEl.addElement(entry.getKey());
					el.addCDATA((String) entry.getValue());
				}
				
			}
			
		}
	}

存储后结果为,与真实正确结果稍有差距,后续需修改,(格式不当与xml头缺失)

<autoFillDef majorVer="1" minorVer="0"><defaultValue><![CDATA[字段86]]></defaultValue><createExpr><![CDATA[updateBizData( null , null )jsonPut( null , null )getRandomDate( null , null )]]></createExpr><calcExpr2><![CDATA[val("fRuleContent")]]></calcExpr2><calcExpr><![CDATA[now()]]></calcExpr></autoFillDef>

总结:处理后台字段类型与前端显示转换时应查找api文档,有支持类型转换的api工具或辅助类可直接使用,总体来说后续还是要多实操,动手掌握

util附件:BlobHelper.java

具体哪个包不清楚了,或者根据自己项目改下导入,我一直以为时java自带的api,需要导包吧

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;

import com.justep.system.data.BlobUtils;

public class BlobHelper {
	public static Timestamp delete(String blobDataModel, String blobConcept, String blobRelation, String blobLastModifiedRelation, String blobConceptValue) throws Exception {
		return BlobUtils.delete(blobDataModel, blobConcept, blobRelation, blobLastModifiedRelation, blobConceptValue);
	}
	
	public static InputStream query(String blobDataModel, String blobConcept, String blobRelation, String blobConceptValue) throws Exception {
		return BlobUtils.query(blobDataModel, blobConcept, blobRelation, blobConceptValue);
	}

	

	public static Timestamp update(String blobDataModel, String blobConcept, String blobRelation, String blobLastModifiedRelation, String blobConceptValue, String limitSize, InputStream blobData) throws Exception {
		return BlobUtils.update(blobDataModel, blobConcept, blobRelation, blobLastModifiedRelation, blobConceptValue, limitSize, blobData);
	}
	
	public static String streamToString (InputStream inputStream){
		if(null==inputStream) return null;
		 
        try {
            ByteArrayOutputStream boa=new ByteArrayOutputStream();
            int len=0;
            byte[] buffer=new byte[1024];
 
            while((len=inputStream.read(buffer))!=-1){
                boa.write(buffer,0,len);
            }
            inputStream.close();
            boa.close();
            byte[] result=boa.toByteArray();
            String temp=new String(result);
 
//识别编码
            if(temp.contains("utf-8")){
                return new String(result,"utf-8");
            }else if(temp.contains("gb2312")){
                return new String(result,"gb2312");
            }else if(temp.contains("gbk")){
                return new String(result,"gbk");
            }else{
                return  temp;
            }
 
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
 
    
	

	}
	
	public static InputStream strToStream(String str){
		InputStream is=null;
		if(null==str)return is;
		ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(str.getBytes());
		is=(InputStream)byteArrayInputStream;
		
		return is;
	}
	
}
### 如何在 Oracle 数据库中存储 Java Map 类型数据 为了在 Oracle 数据库中有效地存储来自 Java 的 `Map` 类型数据,可以采用多种策略。一种常见的方式是通过序列化或转换JSONXML 格式来保存这些键值对。 #### 使用 JSON 存储方式 现代版本的 Oracle 支持原生 JSON 文档处理功能。这使得可以直接将 Java 中的 `Map<String, Object>` 转换JSON 字符串,并将其作为 CLOB 或 VARCHAR2 列中的字符串存入表中: ```sql CREATE TABLE my_table ( id NUMBER GENERATED BY DEFAULT AS IDENTITY, json_data CLOB CHECK (json_data IS JSON), PRIMARY KEY(id) ); ``` 对于应用程序而言,则可以在插入之前先将 `Map` 对象转成 JSON 形式的字符串: ```java import com.fasterxml.jackson.databind.ObjectMapper; // 将 Map 转换JSON 字符串 ObjectMapper mapper = new ObjectMapper(); String jsonString = mapper.writeValueAsString(yourJavaMap); // 插入到数据库 PreparedStatement pstmt = connection.prepareStatement( "INSERT INTO my_table(json_data) VALUES (?)"); pstmt.setString(1, jsonString); int affectedRows = pstmt.executeUpdate(); ``` 这种方法不仅简单易行,而且便于后续查询操作时解析回原始结构[^1]。 #### 序列化为 BLOB 方案 另一种方案涉及将整个 `HashMap` 进行二进制序列化后作为一个大对象(BLOB)写入数据库。不过这种方式不如前者直观,也不利于直接读取其中的内容;除非有特殊需求,通常不推荐这样做。 #### 创建自定义类型映射 如果希望更紧密地集成两者之间的交互,还可以考虑创建用户定义的数据类型(UDT),即在 PL/SQL 层面构建类似于哈希表的对象模型,再配合 JDBC 驱动程序完成双向转换工作。然而这种做法相对复杂得多,适用于特定场景下的高级应用开发[^2]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值