MyBatis MapperProvider MessageFormat拼接批量SQL语句执行报错的原因分析及解决办法
程序员文章站
2022-04-14 11:34:32
最近在项目中有这么一段代码:下载服务器基础业务数据进行本地批量插入操作,因项目中使用mybatis进行持久化操作,故直接考虑使用mybatis的批量插入功能。
1.以下是...
最近在项目中有这么一段代码:下载服务器基础业务数据进行本地批量插入操作,因项目中使用mybatis进行持久化操作,故直接考虑使用mybatis的批量插入功能。
1.以下是mapper接口的部分代码
public interface printmapper { @insertprovider(type = printmapperprovider.class,method = "insertalllotwithvehiclecode4h2") void insertalllotwithvehiclecode(list<lotwithvehiclecodebo> lotwithvehiclecodes); }
2.对应mapperprovider中函数片段
public string insertalllotwithvehiclecode4h2(map<string,list<lotwithvehiclecodebo>> map) { list<lotwithvehiclecodebo> lotwithvehiclecodebos = map.get("list"); stringbuilder sb = new stringbuilder("insert into mtc_lot_with_vehicle_code (lot_code,product_vehicle_code) values "); messageformat messageformat = new messageformat("(" + "#'{'list[{0}].lotcode }," + "#'{'list[{0}].productvehiclecode }" + ")"); int size = lotwithvehiclecodebos.size(); for (int i = 0; i < size; i++) { sb.append(messageformat.format(new object[]{i})); if (i < size - 1) sb.append(","); } return sb.tostring(); }
3.service层
@transactionalpublic void synchlotwithvehiclecodetolocaldb(list<lotwithvehiclecodebo> lotwithvehiclecodebos) { if(null != lotwithvehiclecodebos && lotwithvehiclecodebos.size()>0) { printmapper.insertalllotwithvehiclecode(lotwithvehiclecodebos); } }
程序上线的时候没有发生问题,在业务量猛增的时候,大约同时执行500条以上的时候程序就开始报错:
caused by: org.apache.ibatis.builder.builderexception: improper inline parameter map format. should be: #{propname,attr1=val1,attr2=val2} at org.apache.ibatis.builder.sqlsourcebuilder$parametermappingtokenhandler.buildparametermapping(sqlsourcebuilder.java:89) at org.apache.ibatis.builder.sqlsourcebuilder$parametermappingtokenhandler.handletoken(sqlsourcebuilder.java:43) at org.apache.ibatis.parsing.generictokenparser.parse(generictokenparser.java:25) at org.apache.ibatis.builder.sqlsourcebuilder.parse(sqlsourcebuilder.java:24) at org.apache.ibatis.builder.annotation.providersqlsource.createsqlsource(providersqlsource.java:57) ... 61 more
异常已指明sql语句构建问题,debug进去:
问题根源:
messageformat messageformat = new messageformat("(" + "#'{'list[{0}].lotcode }," + "#'{'list[{0}].productvehiclecode }," + ")"); int size = lotwithvehiclecodebos.size(); for (int i = 0; i < size; i++) { sb.append(messageformat.format(new object[]{i})); if (i<size-1) sb.append(","); }
当size达到3位数以上时构建出的message为:
(#{list[1,000].lotcode },#{list[1,000].productvehiclecode })
解决办法:messageformat.format(new object[]{i+""}
上一篇: sql存储过程几个简单例子
下一篇: SQL中 decode()函数简介