说明:本文重在讲述如何使用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传参情况,但保证按照上面的情况写绝对不会出错。好了,吃饭去了。
觉得本篇文章对你有价值的话,点个赞再走呗!