MyBatis MapperProvider MessageFormat Concatenates the Cause Analysis and Solution for batch SQL statement execution errors. mybatismapper
Recently, there was a piece of code in the project: Download the basic service data of the server for local batch insert operations, because the project uses mybatis for persistent operations, it is directly considered to use the mybatis batch insert function.
1. The following is part of the Mapper interface code.
public interface PrintMapper{@InsertProvider(type = PrintMapperProvider.class,method = "insertAllLotWithVehicleCode4H2") void insertAllLotWithVehicleCode(List<LotWithVehicleCodeBO> lotWithVehicleCodes);}
2. corresponding to the function segment in 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 Layer
@Transactionalpublic void synchLotWithVehicleCodeToLocalDB(List<LotWithVehicleCodeBO> lotWithVehicleCodeBOs){ if(null != lotWithVehicleCodeBOs && lotWithVehicleCodeBOs.size()>0){printMapper.insertAllLotWithVehicleCode(lotWithVehicleCodeBOs);}}
There was no problem when the program went online. When the business volume soared, the program started to report an error when about 500 or more programs were executed simultaneously:
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
The SQL statement build problem has been specified for the exception. DEBUG the problem:
Root cause:
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(",");}
When the size exceeds three digits, the constructed message is:
(#{list[1,000].lotCode },#{list[1,000].productVehicleCode })
Solution: messageFormat. format (new Object [] {I + ""}
Articles you may be interested in:
- Analysis on the Application of Mybatis in CS Program
- Java uses the mybatis Interceptor to calculate the SQL Execution time example
- SpringMVC + MyBatis declarative Transaction Management
- MyBatis quick start tutorial (1)-MyBatis Quick Start
- Detailed description of dynamic SQL of mybatis (excellent)
- Java simple implementation SpringMVC + MyBatis paging plug-in
- Solve springmvc + mybatis + mysql Chinese garbled Problem
- Deep analysis on saving and reading of MySQL Database BLOB fields
- Oracle + mybatis uses dynamic SQL to implement batch insert when the inserted fields are uncertain