Java-Mybatis 错误-Could not set parameters for mapping: ParameterMapping{property='flowType'

2023年08月23日 15:48 · 阅读(1105) ·

问题描述

Mapper

  1. /**
  2. * 生成新增数据的申请单号(流程编号)
  3. *
  4. * @param flowType 流程类型 {@link com.tencent.finance.enums.FlowTypeEnum}
  5. * @return 申请单号
  6. */
  7. FlowNoVO generateFlowNo(@Param("flowType") String flowType);

Mapper.xml

  1. <select id="generateFlowNo"
  2. parameterType="java.lang.String"
  3. resultType="com.tencent.finance.model.entity.FlowNoVO">
  4. select max(t.flow_no) flow_no
  5. , concat(date_format(now(), '%Y%m%d'), '-#{flowType}-') flow_pre
  6. from smallflow_basic_information t
  7. where t.flow_type = #{flowType}
  8. and t.flow_no like concat(date_format(now(), '%Y%m%d'), '-#{flowType}-%')
  9. </select>

调用报错

  1. {
  2. "code": 400,
  3. "message": "nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='flowType', mode=IN, javaType=class java.lang.Object, jdbcType=VARCHAR, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #2 with JdbcType VARCHAR . Try setting a different JdbcType for this parameter or a different configuration property. Cause: org.apache.ibatis.type.TypeException: Error setting non null for parameter #2 with JdbcType VARCHAR . Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.lang.reflect.UndeclaredThrowableException"
  4. }

问题分析

  • 原因是使用 #{} 会把对应变量添加一个单引号 '

  • 在下面两个 SQL 语句中,已经有单引号了,在其中使用 #{} 会再添加单引号导致解析错误

  1. concat(date_format(now(), '%Y%m%d'), '-#{flowType}-')
  2. concat(date_format(now(), '%Y%m%d'), '-#{flowType}-%')

问题解决

  • 修改 Mapper.xml,在单引号中使用 ${} 替换 #{}
  1. <!--生成新增数据的申请单号(流程编号)-->
  2. <select id="generateFlowNo"
  3. parameterType="java.lang.String"
  4. resultType="com.tencent.finance.model.entity.FlowNoVO">
  5. select max(t.flow_no) flow_no
  6. , concat(date_format(now(), '%Y%m%d'), '-${flowType}-') flow_pre
  7. from smallflow_basic_information t
  8. where t.flow_type = #{flowType}
  9. and t.flow_no like concat(date_format(now(), '%Y%m%d'), '-${flowType}-%')
  10. </select>

附:本案例中序列的生成方式

Impl

  1. /**
  2. * 生成新增数据的申请单号(流程编号)
  3. *
  4. * @param flowType 流程类型 {@link com.tencent.finance.enums.FlowTypeEnum}
  5. * @return 申请单号
  6. */
  7. @Override
  8. public String generateFlowNo(String flowType) {
  9. String msg;
  10. String logInfo = "generateFlowNo >> {}";
  11. String key = FlowTypeEnum.getCodeByKey(flowType);
  12. if (CommonUtil.isNull(key)) {
  13. msg = String.format("流程类型“%s”不正确", flowType);
  14. log.info(logInfo, msg);
  15. return null;
  16. }
  17. FlowNoVO flowNoVO = baseMapper.generateFlowNo(flowType);
  18. String flowNo = flowNoVO.getFlowNo();
  19. String flowPre = flowNoVO.getFlowPre();
  20. if (CommonUtil.isNull(flowNo)) {
  21. flowNo = flowPre + "001";
  22. } else {
  23. String noStr = flowNo.split("-")[2];
  24. int no = Integer.parseInt(noStr) + 1;
  25. if (no >= 1000) {
  26. flowNo = flowPre + no;
  27. } else {
  28. flowNo = flowPre + CommonUtil.getSeqLengthStr(no, 3);
  29. }
  30. }
  31. return flowNo;
  32. }

CommonUtil.getSeqLengthStr

  1. /**
  2. * 获取指定长度的序列号
  3. *
  4. * @param seqNumber 序列数字,例如 1
  5. * @param lenght 指定长度,例如 3
  6. * @return 返回指定长度的序列号,比如序列数字 1,指定长度 3,返回 001
  7. */
  8. public static String getSeqLengthStr(Integer seqNumber, Integer lenght) {
  9. //seqNumber = seqNumber + 1;
  10. String seqNumberStr = String.valueOf(seqNumber);
  11. if (seqNumberStr.length() >= lenght) {
  12. return seqNumberStr;
  13. }
  14. StringBuilder sb = new StringBuilder();
  15. int count = lenght - seqNumberStr.length();
  16. for (int i = 0; i < count; i++) {
  17. sb.append("0");
  18. }
  19. sb.append(seqNumberStr);
  20. return sb.toString();
  21. }

Mapper

  1. /**
  2. * 生成新增数据的申请单号(流程编号)
  3. *
  4. * @param flowType 流程类型 {@link com.tencent.finance.enums.FlowTypeEnum}
  5. * @return 申请单号
  6. */
  7. FlowNoVO generateFlowNo(@Param("flowType") String flowType);

Mapper.xml

  1. <!--生成新增数据的申请单号(流程编号)-->
  2. <select id="generateFlowNo"
  3. parameterType="java.lang.String"
  4. resultType="com.tencent.finance.model.entity.FlowNoVO">
  5. select max(t.flow_no) flow_no
  6. , concat(date_format(now(), '%Y%m%d'), '-${flowType}-') flow_pre
  7. from smallflow_basic_information t
  8. where t.flow_type = #{flowType}
  9. and t.flow_no like concat(date_format(now(), '%Y%m%d'), '-${flowType}-%')
  10. </select>

例如

  1. -- 获取对应类型最大的流程编号
  2. select max(t.flow_no) flow_no
  3. ,concat(date_format(now(),'%Y%m%d'),'-04-') flow_pre
  4. from smallflow_basic_information t
  5. where t.flow_type = '04'
  6. and t.flow_no like concat(date_format(now(),'%Y%m%d'),'-04-%')

结果

flow_no flow_pre
20230823-04-

调用结果

  1. //20230823-04-001
  2. String no = generateFlowNo('04');

附:其它序列生成方式

Oracle-seqence(序列 ),手动序列