由于mybatis在加载参数时不根据名字区分,所以在传入多个参数时如果与传入一个参数的使用方式一样,会参数混乱,异常为BindingException,解决方案如下:
例子:
// javabean
public class User {
private int id;
private String name;
private byte age;
// 忽略了getter、setter方法
}
1.xml文件中使用param1、param2 ......注意下标是从1开始,分别对应接口中方法参数的位置,除此之外,也可以使用args0、args1 .......注意下标是从0开始
// 接口
public interface UserMapper {
List<User> select(String name,byte age);
}
// 映射文件
<select id="select" resultType="model.User">
select * from `user` where name = #{arg0} and age =#{arg1}
</select>
// or
<select id="select" resultType="model.User">
select * from `user` where name = #{param1} and age =#{param2}
</select>
2.在接口方法中,在参数前添加@Param注解,注解参数为想使用的名称
// 接口
public interface UserMapper {
List<User> select(@Param("name") String name,@Param("age") byte age);
}
// 映射文件
<select id="select" resultType="model.User">
select * from `user` where name = #{id} and age =#{age}
</select>
注意:@Param注解的参数不一定要与接口方法的参数名一致,如上述例子中@Param("name")可以使用@Param("username")等,而名为name的String类型参数继续使用name
但是:xml文件中占位符的名称必须与@Param注解中的参数名保持一致,即@Param("name")时使用#{name},而@Param("username")时使用#{username},这是由于mybatis不识别层接口中方法的参数名而识别@Param注解中的参数名引起的
3.封装到一个对象中,直接使用其属性名即可
// 接口
public interface UserMapper {
List<User> select(User user);
}
// 映射文件
<select id="select" resultType="model.User">
select * from `user` where name = #{id} and age =#{age}
</select>
注意:由于xml文件中必须有一个BaseResultMap,所以,如果传入的对象时该BaseResultMap对应的对象类型或者传入的对象的属性都可以通过BaseResultMap中的映射对应,则可以直接使用,如果不对应的属性或者有额外的属性,需要在xml文件中添加自定义的ResultMap来进行对应。
如:传入的参数对象为User对象,则可以直接使用
<resultMap id="BaseResultMap" type="model.User">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="age" property="age" />
</resultMap>
如:传入的参数对象为某个其他类对象,如果此时使用BaseResultMap中没有的phone属性,如果是查询结果使用该类,没有该属性,该属性的返回结果为null,其他属性正常,
如果是传参,没有改属性则会报错,需添加新的ResultMap
<resultMap id="UserVOResultMap" type="model.UserVO">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="age" property="age" />
<result column="phone" property="phone" />
</resultMap>
4.封装到一个Map中,直接使用其key即可
//封装map,仅用于说明问题,至于id为几是不是唯一不做考究
Map<String,Object> map= new HashMap();
//key为id,value为2
params.put("id", 2);
params.put("age", 32);
// 接口
public interface UserMapper {
List<User> select(Map<String,Object> map);
}
// 映射文件
<select id="select" paramerterType="java.util.Map" resultType="model.User">
/* #{id}中的id为map中的key,操作时代入得是其value */
select * from `user` where id= #{id} and age =#{age}
</select>
注意:update、insert、delete操作与select操作在传参数时是一样的,之前在进行update操作时,
纠结于update标签的parameterType属性,认为是必须写的属性,
看到第二个博主的博客后结合之前写的select语句才恍然大悟
其他补充请参考:https://blog.csdn.net/weixin_37891479/article/details/80525612
https://www.cnblogs.com/lzpsir/p/11985751.html