还在为mybatis接口传参而发愁吗?一篇文章解决你的问题

说明:本文重在讲述如何使用mybatis在dao层正确的写参数,并在sql映射文件中正确是使用dao层传过来的参数,基本涵盖了mybatis使用过程中绝大部分场景,至于为什么要这样做,有兴趣的小伙伴可以研究下mybatis的源码,相信一定会收获满满!

下面开始,关于mybatis接口传参分为两种情况:

一、参数参与了动态sql

看一个常见的问题:
dao层:

public Person getPerson(String personName);

sql映射文件:

<select id="getPerson" resultType="com.test.Person">
  select * from t_person
  where 1 = 1
  <if test="personName != null and personName !=''">
     person_name = #{personName}
  </if>
</select>

报错There is no getter for property named 'personName' in 'class java.lang.String'。意思是String类没有personName属性的getter方法,他确实是没有,因为他本来就没有personName属性的getter方法。
原因:参与动态sql时,mybatis会以OGNL对象树的形式即String.personName取值,导致异常抛出。
解决:@Param注解指定key,然后使用该key。
即dao层这样:

public Person getPerson(@Param("personName") String personName);

sql映射文件这样:

<if test="personName != null and personName !=''">
     person_name = #{personName}
  </if>

下面说明一些正确的处理方法:

1、单个参数时

@Param注解指定key。就像上面的解决方法那样

2、多个参数时

@Param注解分别指定key
例如:

getPerson(@Param("personName") String personName,@Param("age") Integer age);

取值就根据@param注解里面的名称取就行。

3、参数为实体类

方式一:@Param注解指定变量名后,用变量名.属性名取值
例如:
dao层:

insertUser(@param("u") User user);

sql映射文件:

values (#{u.username},#{u.phone})

方式二:直接属性名取值
例如:

dao层:insertUser(User user);
sql映射文件:#{realName}取值。假设user对象有个realName属性

4、参数为map

方式一:@Param注解指定变量名后,用变量名.key取值
例如:
dao层

selectUserList(@param("paramMap") Map<String,Object> paramMap);

sql映射文件:

<if test="paramMap.state != null">
     state = #{paramMap.state}
  </if>

方式二:直接key取值

dao层:insertUser(Map<String,Object> paramMap);
sql映射文件:
<if test="state != null">
     state = #{state} //假设paramMap里有个key为state的entry
  </if>

5、参数为List、Set、数组

@Param注解指定变量名或者直接使用list、set、array。然后foreach标签进行遍历,#{}取遍历出来的item的值即可;若item是对象,就对象.属性方式取,例如:
dao层:

updateBatch(@param("partList") List<Part> partList);
updateBatch(@param("userSet") Set<Part> partSet);
updateBatch(@param("userArr") Part[] partArr);

sql映射文件:

<foreach collection="partList" item="part">
 		update jxc_stock
 		set productNum = productNum + #{part.quantity}
 		where warehouseId = #{part.warehouseId}
</foreach>

统一记忆:
只要参与动态sql,就用@Param注解指定变量名,一层关系的直接取值,两层关系的xxx.属性名取值

二、没参与动态sql

1、单个参数时

直接#{参数名}取值;
参数为一个POJO时,#{属性名}取值;
参数为一个Map时,#{key}取值;

2、多个参数时

1)方法的入参处使用@Param明确变量名
例如:
dao层:

public Employee getEmployeeById(@Param("id")Integer id2,@Param("lastName") String lastName2);

sql映射文件:

<select id="getEmployeeById">
select * from employee where id=#{id} and last_name=#{lastName}
</select>

2)其中的一个参数为POJO时
@Param注解指定变量名,然后变量名.属性名 取值
例如:
dao层:

public Employee getEmp(@param("id") Integer id,@Param("e")Employee emp);

sql映射文件:

取值:id==>#{id}/#{param1}    lastName==>#{e.lastName}/#{param2.lastName}

3)其中的一个参数为Map时
@Param注解指定变量名,然后变量名.key 取值。
例如:同2)POJO时

原理:
当接口的参数有多个时,Mybatis默认会将多个参数封装成一个map集合。
key:是param1,param2…paramN value:就是传入的值。
例如:select * from employee where id=#{param1} and last_name=#{param2}

统一:
只要没参与动态sql,单个参数时直接#{key}取值(pojo和map也是这样),多个参数时用@param注解标注,一层关系直接取值,两层关系用xxx.属性名的方式取值

三、最后

        以上就是全部内容了,能理解就理解,理解不了就记忆,实在记不住就收藏本文章,以后遇到不知道怎么写或问题时,可以过来查一下你是哪种情况。本篇文章不保证涵盖所有的mybatis传参情况,但保证按照上面的情况写绝对不会出错。好了,吃饭去了。

觉得本篇文章对你有价值的话,点个赞再走呗!

  • 37
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值