mybatis参数处理过程及原理

本文深入探讨了MyBatis框架中参数传递的多种方式,包括直接使用#{}

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

无法获取参数

在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中,多个参数会被封装成一个mapmap中的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的区别

具体的区别我就不细说了,可以参考一下这篇文章#{}和${}的区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值