Mybatis的初学者一定对sql映射文件中许多的#{}符号感到陌生。其实我们都知道,它可以理解为一个占位符,把传递过来的数据放到sql语句中,但有些时候它又我觉得困惑,最后大致了解了一下,下面说一下我所学到的知识。
#{}符号大致有以下三种用途:
1. 获取传递来的原始类型参数
我们经常将操作方法定义在一个接口里面。当我们在接口里定义诸如
User getUser(Integer id);
的方法时,我们需要向Mybatis传递一个整型参数 id,这时候,许多教程上的映射文件就是这么写的:
<select id="getUser" resultType="com.User">
select * from user where id = #{id}
</select>
那我们就会情不自禁地想了:#{id}就是代指我传递过来的参数呗,也就是说,参数名是啥#{}就填啥呗,但事实是不论你写#{name}
、#{gender}
、#{fuck}
程序都能正确运行。这是因为,当只有一个参数传递时,Mybatis不会对其作特殊处理,不管你大括号里写的什么,它都会用参数替换。 它真的就只是一个占位置的。
那么多个参数呢?
User getUser(Integer id, String name);
如果你这么写:
<select id="getUser" resultType="com.User">
select * from user where id = #{id} and name = #{name}
</select>
就会发现刺眼的报错信息了。实际上,当有多个参数(不止是原始类型)传递时,Mybatis会对它们做特殊处理——封装成Map,其中键是param1, param2, param3…类推,键才是传递过来的参数,我们在#{}中写的需是键,也就是#{param1}
,#{param2}
,或是它们的下标#{0}
,#{1}
。但这样也未免太麻烦,所以现在主要采用写 命名参数 的方法:
在声明接口时用注解命名参数,就相当于自己命名参数的键名:
User getUser(@Param("id")Integer id, @Param("name")String name);
这样一来上面的报错信息就消失了。
另外,如果传入的是一个Collection或数组类型的参数,Mybatis也会把它封装成Map,这时候如果不自己命名的话键是固定的:“collection"或"list"或"array”。
2. 获取对象中的属性值
这个就好理解了,当参数只有一个并且是个JavaBean对象POJO时,#{}里面就写这个对象的属性名,Mybatis就能把它取出来。例如:
JavaBean
public class User {
Integer userid;
String username;
Character gender;
//...
}
接口
User getUser(User user);
sql
<select id="getUser" resultType="com.User">
select * from user where id = #{userid} and name = #{username}
</select>
3. 获取Map中的值
当我们传入一个Map后,#{}里写键,那么Mybatis就会取出值来。
不得不说,Mybatis真的是既简便又强大!