项目: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对象,达到不重复的目的。