MyBatis映射器中检查参数是否传入及BindingException处理方案
解决MyBatis Map参数缺失引发BindingException的实用方案
SQL映射里用
<if>做参数存在性校验
编写SQL时,对每个可能缺省的参数先判断是否存在(按需加上非空校验),再拼接对应条件。示例:<select id="getUserList" parameterType="java.util.Map" resultType="User"> SELECT id, username, age FROM user <where> <if test="username != null and username != ''"> AND username LIKE CONCAT('%', #{username}, '%') </if> <if test="age != null"> AND age = #{age} </if> </where> </select>这样MyBatis只会处理Map里存在的参数,不会尝试绑定不存在的key,从根源避免绑定异常。
提前给Map补全默认值
前端JSON转成Map后,给所有SQL中可能用到的参数设置默认值(空字符串、null或0都可),保证Map里始终有对应的key。用Java 8+的putIfAbsent可简化操作:Map<String, Object> queryParams = new HashMap<>(frontEndParams); // 补全所有可能用到的参数key queryParams.putIfAbsent("username", ""); queryParams.putIfAbsent("age", null); queryParams.putIfAbsent("status", 0);就算前端没传这些参数,Map里也有对应的key,MyBatis绑定的时候就不会找不到参数。
换成实体类接收参数(适合参数相对固定的场景)
如果前端传的参数虽然偶尔缺省,但字段范围相对固定,不如定义一个实体类,给字段设置默认值(或让字段默认为null),用实体类代替Map作为参数。MyBatis会自动识别实体类的字段,哪怕前端没传,字段也有默认值,不会抛出绑定异常。比如:public class UserQueryDTO { private String username = ""; private Integer age; private Integer status = 1; // getter、setter方法 }之后Mapper接口直接用这个DTO作为参数类型即可。
用
@Param注解明确参数来源
如果坚持用Map,可以在Mapper接口方法上用@Param给Map起个名字,然后在SQL里通过这个名字引用参数,同时配合<if>判断:List<User> getUserList(@Param("params") Map<String, Object> params);对应的SQL:
<select id="getUserList" resultType="User"> SELECT id, username, age FROM user <where> <if test="params.username != null and params.username != ''"> AND username LIKE CONCAT('%', #{params.username}, '%') </if> </where> </select>这种方式能避免参数名冲突,也让参数引用更清晰,减少绑定异常的概率。
内容的提问来源于stack exchange,提问作者user4739287
相关产品推荐
相关产品推荐

