开发问题总结(一)

项目:java前后端开发

问题描述:

需要重写此方法 ExeProcedureBatchWitchQX_2Out ,调用方法传入四个参数。

1.增加对数据的批量处理。   

2.增加事务回滚(如果数组中某一个数据有问题,可以把之前执行成功的回滚)

3.在传参数的时候,createDeliveBySplit中的第二个的存储过程sql语句的delivery_id参数来自前一个存储过程

问题是createDeliveBySplit已经固定好了参数,直接传到ExeProcedureBatchWitchQX_2Out的方法中。

public static String[] createDeliveBySplit(Map<String, Object> params) {
	String[] rtnMsg = null;
	String delivery_id = "";
	String argSql ="PCK_DELIVEBILL.P_B2B_GET_DELIVERY_BY_PURORDER(?,?,?,?,?,?,?,?)";
	String argSqls  = "PCK_DELIVEBILL.P_B2B_SPLIT2DELIVERY_AND_ISC(?,?,?,?,?,?,?,?,?,?,?,?,?)";
	List<List<Object>> proargs = new ArrayList<List<Object>>();
	List<List<Object>> prosargs = new ArrayList<List<Object>>();
		
	String deliveryArray = StringUtils.object2String(params.get("deliveryArray"));
	JSONArray items = JSONArray.fromObject(deliveryArray);
		
	for (int i = 0; i < items.size(); i++) {
		List<Object> arg = new ArrayList<Object>();
		List<Object> args = new ArrayList<Object>();
		JSONObject item = items.getJSONObject(i);
			
		arg.add(item.getString("purorder_split_id"));
		arg.add(item.getString("purorder_id"));
		arg.add(item.getString("balance_modle"));
		arg.add("00");
		arg.add(item.getString("creater"));
		arg.add(item.getString("remark"));
		proargs.add(arg);
			
		args.add(item.getString("purorder_split_id"));
		args.add(item.getString("purorder_id"));
		args.add(item.getString("purorder_detail_id"));
		args.add(item.getString("split_qty"));
		args.add(item.getString("batch_no"));
		args.add(item.getString("mfd"));
		args.add(item.getString("end_dt"));
		args.add(item.getString("product_dt"));
		args.add(item.getString("approval_number"));
		args.add(delivery_id);
		args.add(item.getString("creater"));
		prosargs.add(args);
			
	}
     rtnMsg = DataSourceUtil.ExeProcedureBatchWitchQX_2Out
                                   (argSql, proargs, argSqls, prosargs);
						
		 return rtnMsg;
}
public static String[] ExeProcedureBatchWitchQX_2Out(
String sql, List<List<Object>> arg,String sqls, List<List<Object>> args) {
	Connection conn = null;
	CallableStatement proc = null;
			
	Connection conns = null;
	CallableStatement procs = null;
			
	String rtnStr[] = new String[] { "", "" };
	boolean isError=false;
	String delivery_id = "";
	try {
	conn = getQXPoolConnection();
	proc = conn.prepareCall("{ call " + sql + " }");
	proc.setQueryTimeout(BaseDao.QUERYTIMEOUT);
			
	for(int i = 0; i < arg.size(); i++){
				
	int length =  arg.get(i).size();
			
	for (int z = 0; z <length; z++) {
		proc.setObject(z + 1, arg.get(i).get(z));	
	}
	proc.registerOutParameter(arg.get(i).size() + 1, Types.NUMERIC);
	proc.registerOutParameter(arg.get(i).size() + 2, Types.VARCHAR);
	proc.execute();
	rtnStr[0] = proc.getInt(arg.get(i).size() + 1) + "";
	rtnStr[1] = proc.getString(arg.get(i).size() + 2);
	delivery_id = rtnStr[1];
	arg.clear();
	if ("1".equals(rtnStr[0])) {
        isError = true;
        conn.rollback();
        break;
        } 
			
	args.get(i).set(9, delivery_id);
			
	conns = getQXPoolConnection();
 	procs = conns.prepareCall("{ call " + sqls + " }");
 	procs.setQueryTimeout(BaseDao.QUERYTIMEOUT);
 			
	for (int z = 0; z < args.get(i).size(); z++) {
		procs.setObject(z + 1, args.get(i).get(z));	
	}
	procs.registerOutParameter(args.get(i).size() + 1, Types.NUMERIC);
	procs.registerOutParameter(args.get(i).size() + 2, Types.VARCHAR);
	procs.execute();
	rtnStr[0] = procs.getInt(args.get(i).size() + 1) + "";
	rtnStr[1] = procs.getString(args.get(i).size() + 2);
	args.clear();
	if ("1".equals(rtnStr[0])) {
        isError = true;
        conns.rollback();
        break;
        } 
    }
            	
	if (!isError)
	{
	   conn.commit();
	}
          
	} catch (Exception ex) {
		ex.printStackTrace();
		rtnStr[0] = "1";
		rtnStr[1] = "ERROR";
		return rtnStr;
	} finally {
		closeConn(conn, proc, null);
		closeConn(conns, procs, null);
	}
		return rtnStr;
}

解决办法:

1.对于参数的传递,一开始的想法是传入sql和list数组,但是发现,只传递数组的话,会出现不能进行批量处理的问题,也只能对数据进行单个的处理。所以对传的数组加一个嵌套,根据外层数组的长度,对list外层数组进行循环获得每一个内层嵌套数组的数据,再进行处理,达到批量处理的目的。

2.事务回滚,再调用完存储过程以后,能的到一个String的数组返回值,0是成功,1是失败。通过对返回值判断,如果失败就进行回滚。做完整个循环以后,在外层再进行commit。

3.把值添加到下一个数组里,通过ArrayList的set方法。找到对应的下标,index的值是从0开始。args.get(i).set(9, delivery_id).

其他问题:

在传递参数的时候,把数据添加到List<List<Object>> proargs里时,proargs.add(arg) 随后我对arg.clear,问题来了,proargs直接也被清空。是因为传递的只是一个引用,所以直接被清空了。假如不清空又会导致每一次arg里面在原来有值的情况下,增加新的只,会导致重复。

解决办法:

因为只是引用重复,所以把arg的new方法放在for循环里面,这样每次进行循环的时候就会新建一个arg对象,达到不重复的目的。

猜你喜欢

转载自blog.csdn.net/qq_42773718/article/details/82141906