为什么 Mapper 接口方法要使用 @Param 注解?不使用可以吗?
一、为什么需要ParamMyBatis 通过参数名来映射 SQL 中的#{xxx}占位符。当接口方法有多个参数时MyBatis 默认无法直接获取参数名称Java 编译后参数名会丢失除非开启-parameters编译选项因此需要借助Param注解显式指定参数名称。示例javaListContractEquipmentVO queryContractEquipmentV2( Param(stationList) ListInteger stationList, Param(contractCode) String contractCode );在 XML 中就可以使用#{stationList}和#{contractCode}正确取值。二、不使用Param可以吗分情况讨论场景是否可以不用Param说明单个参数✅ 可以MyBatis 会自动将参数值映射到#{任意名称}如#{id}、#{value}都行XML 中无需Param。多个参数❌ 不推荐但“技术上”可能如果不加ParamMyBatis 会使用默认参数名arg0,arg1或param1,param2取决于版本和配置。SQL 中必须写成#{arg0}、#{arg1}非常不直观且容易出错。示例不推荐javaListContractEquipmentVO queryContractEquipmentV2(ListInteger stationList, String contractCode);XML 中必须写xmland tce.station_id in foreach collectionarg0 ... !-- 或 param1 -- ... when testarg1 SBZT_V1.0 !-- 或 param2 --这种代码可读性极差参数顺序一变就全错。三、为什么不推荐省略Param可读性差arg0、arg1无法表达业务含义维护困难。脆弱性调整方法参数顺序会导致所有argN索引变化难以排查。类型安全Param让 IDE 能识别参数名提供代码提示和重构支持。MyBatis 版本差异早期版本默认参数名为param1,param2不同行为可能混乱。四、最佳实践多参数 → 必须使用Param即使开启-parameters编译选项也建议显式标注避免依赖编译器行为。单参数 → 可选但为了一致性也可以加上。五、回到代码您的接口有stationList和contractCode两个参数且 XML 中使用了#{stationList}和#{contractCode}必须在参数前加Param否则 MyBatis 无法解析会抛出类似Parameter stationList not found的异常。结论不加不行必须加Param。