JAVA解析JSON生成sql语句,数据以文件的方式存档

JSON解析 同时被 3 个专栏收录
1 篇文章 0 订阅
1 篇文章 0 订阅
1 篇文章 0 订阅

最近工作需求中有一个解析层级JSON报文,根据json的key生成建表语句,json的value入库的功能,实现过程有些许坎坷,好在最终简单的实现了,还是觉得写的不够完美,现在将代码分享出来,希望有更优解的大佬可以帮忙优化优化。

项目中使用的是hive仓库,直接上代码吧。

import java.text.SimpleDateFormat;
import java.net.URI;
import java.net.URISyntaxException;
import java.io.FileWriter;
import java.io.IOException;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONTokener;
import java.util.*;
import java.sql.*;

/**
 * JSONObject解析生成sql语句以及文件
 * @author jiaming.wu
 *
 */
@BeanConfig(appId = "jsonToSql",beanId = "JsonToSql",JsonToSql= "DmpIDMEmployee",beanType = BeanType.CONTROLLER,autowired = true,singleton = true,hotMode = true)
@RestConfig(url = "/rest/jsontosql")
public class JsonToSql{
	

	@RestConfig(configName = "JSON生成文件",method = MethodType.POST,url = "/getData")
	public String getData() throws Exception{
        //此处可以传入JSONString,项目中使用的是接收请求报文
	    String requestBody = RequestUtil.getRequestBody();

	    JSONObject job = new JSONObject(requestBody);
	    String mainTable = "RootTable";
	    
	    JSONObject resultJsonObj = new JSONObject();
	    JSONObject result = castJson(job,mainTable,resultJsonObj);
	    JSONObject finalJsonObj = new JSONObject();
	    finalJsonObj = getResult(finalJsonObj,result,mainTable);
	    
		return finalJsonObj.toString();
	}
	
	
	@RestConfig(configName = "数据初始化",method = MethodType.POST,url = "/upload")
	public String upLoadFile() throws Exception{
	    String requestBody = RequestUtil.getRequestBody();
	    JSONObject infoJob = new JSONObject(requestBody);
	    List<String> filedList = new ArrayList<>();
	    List<String> tableList = new ArrayList<>();
	    filedList = (List<String>)getParams(infoJob);
	    List<String> fileAddrList = new ArrayList<>();
	    List<String> sqlList = new ArrayList<>();
	    
	    JSONObject resultJob = new JSONObject();
	    
	    for(String table : filedList){
	        JSONObject tableJob = infoJob.getJSONObject(table);
	        if(!"".equals(tableJob.getString("tableSql"))){
	            tableList.add("b20_"+tableJob.getString("tableName"));
	            fileAddrList.add(tableJob.getString("tableFile"));
	            sqlList.add(tableJob.getString("tableSql"));
	            //+"TERMINATED BY '\t' LINES TERMINATED BY '\n'"
	        }
	        
	    }
	    resultJob.put("tableList",tableList);
	    resultJob.put("fileAddrList",fileAddrList);
	    resultJob.put("sqlList",sqlList);
        
		return resultJob.toString();
	}
	
	
	/**
     * castJson 主方法 处理报文,生成sql以及文件
     * @author jiaming.wu
     *
     */
	private JSONObject castJson(JSONObject job,String mainTable,JSONObject resultJsonObj)throws Exception{
	    List<String> keyList = new ArrayList<String>();
	    keyList = (List<String>)getParams(job);
	    List<String> sqlList = new ArrayList<String>();
	    String createTableSql = "";
	    String tableFilePath = "";
	    
	   for(String key:keyList){
	        Object obj = job.get(key);
	        if("JSONArray".equals(judgeType(obj.toString()))){
	            JSONArray objArray = (JSONArray)obj;
	            if(objArray.length() != 0 && isjson(objArray.get(0).toString())){
	               for(int i=0; i<objArray.length(); i++){
	                   JSONObject arrJob = new JSONObject();
	                    resultJsonObj.put(key,castJson((JSONObject)objArray.get(i),mainTable+"_"+key,arrJob));
	                   }
	            }else{
	               //当前list转String类型作为当前表的当前key的值
	               sqlList.add(key);
	           }
	        }else if("JSONObject".equals(judgeType(obj.toString()))){
	            //当前obj的key新建表再递归
	           JSONObject newjob = (JSONObject)obj;
	           JSONObject arrJob = new JSONObject();
	           resultJsonObj.put(key,castJson(newjob,mainTable+"_"+key,arrJob));
	        }else{
	            sqlList.add(key);
	        }
	   }
	    resultJsonObj.put("sqlParts",sqlList);
	    java.util.Date date=new java.util.Date();
	    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	    
	    List<String> SqlValues = new ArrayList();
	    SqlValues.add("uniqueId");
	    SqlValues.add(dateFormat.format(date));
	    for(String str : sqlList){
	       if(!"null".equals(job.get(str).toString())){
	           SqlValues.add(job.get(str).toString());
	       }else{
	           SqlValues.add("null");
	           }
	       }
	   tableFilePath = ganerateFile(SqlValues,mainTable);
	       
	   String sql = ganerateSql(sqlList,mainTable);
	   resultJsonObj.put("tableSql",sql);
	   resultJsonObj.put("tableFile",tableFilePath);
	   
	   return resultJsonObj;
	}
	
	
	
	private JSONObject getResult(JSONObject newJob,JSONObject cutarnJob,String rootName)throws Exception{
		List<String> keyList = new ArrayList<String>();
	    keyList = (List<String>)getParams(cutarnJob);
		JSONObject result = new JSONObject();
		result.put("tableName",rootName);
		for (String key : keyList) {
			if ("tableFile".equals(key)) {
				result.put(key,cutarnJob.getString(key));
			}else if("tableSql".equals(key)){
				result.put(key,cutarnJob.getString(key));
			}else if("sqlParts".equals(key)){

			}else{
				getResult(newJob,cutarnJob.getJSONObject(key),rootName+"_"+key);
			}
		}
		newJob.put(rootName,result);
		return newJob;
	}

	
	/**
     * ganerateSql 生成sql语句
     * @author jiaming.wu
     *
     */
	private String ganerateSql(List<String> elementList,String tableName)throws Exception{
	    String createTable = "create table b20_"+tableName+"(wm_uniq_identify string,wm_uniq_updateTime string";
	    for(String element : elementList){
	            createTable += ","+element.replace(".","_")+" string";
	       }
        createTable += ") ROW FORMAT DELIMITED FIELDS ";
        return createTable;
	}
	
	/**
     * ganerateFile 生成数据文件
     * @author jiaming.wu
     *
     */
	private String ganerateFile(List<String> valueList, String tableName) throws Exception{
	    String dst = "/brainNewTest/"+tableName+".txt";
	   
	    StringBuffer sb = new StringBuffer();
	    for(String value : valueList){
	            sb.append(value).append("\t");
	       }
	       sb.deleteCharAt(sb.length()-1);//去掉最后一个分隔符
	       sb.append("\n");
          try{
            FileWriter writer=new FileWriter(dst,true);
    		writer.write(sb.toString());
    		writer.close();
    	} catch (IOException e){
    		e.printStackTrace();
    	}
        return dst;
	}
	
	/**
     * getParams 以StringList的形式返回Json的key
     * @author jiaming.wu
     *
     */
	private List<String> getParams(JSONObject resultJson)throws Exception{
	        JSONObject result = new JSONObject();
	        Iterator<String> keys = resultJson.keys();
	        List<String> keyList = new ArrayList<>();
	        while (keys.hasNext()) {
                String teams = keys.next();
                    keyList.add(teams);
            }
	        return keyList;
	    }
	    
	/**
     * judgeType 判断当前传入的jsonString的类型
     * @author jiaming.wu
     *
     */
	private String judgeType(String jsonStr)throws Exception{
	    if(isjson(jsonStr)){
	    Object typeObject = new JSONTokener(jsonStr).nextValue();
            if (typeObject instanceof org.json.JSONArray) {
                return "JSONArray";
            } else if (typeObject instanceof org.json.JSONObject) {
                return "JSONObject";
            }else{
                return "JSONString";
            }
	    }else{
	        return "JSONString";
	    }
	}
	
	 /**
     * isjson 判断当前传入的jsonString是不是JsonObject
     * @author jiaming.wu
     *
     */
	private boolean isjson(String string){
            try {
                JSONObject jsonStr = new JSONObject(string);
                return  true;
            } catch (Exception e) {
                if(isjsonArray(string)){
                   return  true; 
                }else{
                    return false;
                }
            }
        }
    
    /**
     * isjsonArray 判断当前传入的jsonString是不是jsonArray
     * @author jiaming.wu
     *
     */
    private boolean isjsonArray(String string){
            try {
                JSONArray jsonArray = new JSONArray(string);
                return  true;
            } catch (Exception e) {
            return false;
            }
        }
	
}

以上,代码复制到项目中,将注解部分做一做修改应该直接可以使用,欢迎各位大佬在评论区讨论各种新思路,大家一起学习。
最后,祝工作顺利,生活愉快

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

飞天神仙怪

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值