无法获取参数
在mybatis的映射文件***Mapper.xml
中,如果没有规定传入参数类型,就会发生一些错误
给出一个映射文件
<select id="getPerson" resultType="com.rwh.pojo.person">
select * from person where id = #{id} and name = #{name}
</select>
测试方法
@Test
public void f(){
SqlSession sqlSession = sqlSessionUtils.getSqlSession();
SqlSession sqlSession2 = sqlSessionUtils.getSqlSession();
personMapper mapper = sqlSession.getMapper(personMapper.class);
// person p = new person();
// p.setId(1);
// p.setName("张三");
person person = mapper.getPerson(1, "张三");
// person person = mapper.getPerson(p);
System.out.println(person);
}
执行这个方法的时候出现异常,打印出异常信息:
Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]
说明:在一些通过直接传入参数的业务场景下,如果直接粗暴的通过#{}
获取参数是会发生错误的,在这种情况下只能通过[arg1, arg0, param1, param2]
这种方式获取参数,我们更改一下映射文件
<select id="getPerson" resultType="com.rwh.pojo.person">
select * from person where id = #{param1} and name = #{param2}
</select>
看输出信息:
==> Preparing: select * from person where id = ? and name = ?
==> Parameters: 1(Integer), 张三(String)
<== Columns: id, name, addr, email
<== Row: 1, 张三, shanghai, 123@
<== Total: 1
person(id=1, name=张三, email=123@, addr=shanghai)
可以成功查询出数据!
原因
造成这个现象的原因是:
在mybatis
中,多个参数会被封装成一个map
,map
中的key
就是param1,param2
或其他参数索引,value
就是我们传入的值,而#{}
就是从指定的key
获取value
解决办法:针对不同业务场景用不同的方式获取参数
-
如果传入的参数不符合我们
pojo
里的属性,可以使用@param
注解- 如:
public person getPerson(@Param("id") int id,@Param("name") String name);
这种方式就相当于明确指定封装参数map
中的key
- 如:
-
传入的参数符合
pojo
属性,可以使用parameterType
属性,规定传入的pojo
<select id="getPerson" parameterType="com.rwh.pojo.person" resultType="com.rwh.pojo.person"> select * from person where id = #{id} and name = #{name} </select>
-
在参数过多的情况下可以选择性的使用
Map
#{}
和${}
的区别
说最重要的区别吧:
#{}
采用预编译的方式处理sql
语句,${}
采用拼接字符串的方式且无法避免sql注入
,从
Preparing: select * from person where id = ? and name = ?
就可以看出,相当于statement和prepareStatement
的区别
具体的区别我就不细说了,可以参考一下这篇文章#{}和${}的区别