MyBatis中使用#{}和${}符号获取参数值的区别
1、工程结构的准备
首先编写一个JavaBean:"Employee",使用自动生成全部生成JavaBean每个属性的getter和Setter方法(不会的话,参驾国考下面的引用连接).
接着定义一个接口类"EmployeeMapper",并在接口中定义一个"getEmpByMap" 传入map来处理多个参数的方法.



2、都使用#{}符号配置sql映射文件"EmployeeMapper.xml"
在"EmployeeMapper.xml"中添加一个select语句,获取参数值时都使用#{}符号来获取参数值:
"<select id="getEmpByMap" resultType="com.bean.Employee" databaseId="mysql">
select * from tbl_employee
where id = #{id} and last_name =#{lastName}
</select>".
在这里,方便理解,附上mysql数据库中对应的表"tbl_employee"的信息,下图图二.


3、编写测试类
先编写一个"getSqlSessionFactory()"获取SqlSessionFactory对象的类,然后再编写一个@Test的方法"test05()",使用map方法来获取"id=4,lastName='葫芦娃'"的对象,并进行打印输出.


4、都使用#{}符号的结果与分析
如图所示,初步编译后的sql语句是" select * from tbl_employee where id = ? and last_name =? ";说明, #{} 是以预编译的形式,直接将参数设置到sql语句中; 使用PreparedStatement的sql封装方法:设置了占位符为"?",可以有效地防止sql注入.

5、对比使用${}符号获取参数值率肺够的结果与分析
如图所示,在倘称"EmployeeMapper.xml"中select语句将第一个#{}符号替换成了${}符号;
再次运行测试类,初步编译后的sql语句是" select * from tbl_employee where id = 4 and last_name =? ";在这里,我们可以看到使用了${}获取参数后,id=" 4 ",没有占位符"?".
因为, ${}的作用: 取出的参数值会直接封装在sql语句中,不能防止sql注入,会有安全问题.


6、当获取的参数值是表名的时候,#{}支持,${}不支持
在测试类中,将表名加进map参数中,"map.put("table_name", "tbl_employee");";
然后更改"EmployeeMapper.xml"的select语句为" select * from #{table_name} ...",尝试使用#{}来获取别名,运行显示了"MySQLSyntaxErrorException"错误,故不支持使用#{}来获取Map参数列表中的表名.
更改为${}来使用,运行成功,sql语句为:"select * from tbl_employee where id = 4 and last_name = ?",故可以使用${}来获取Map参数列表中的表名.



7、7.总结: 怎么合理使用#{}和${}符号获取参数值
大多数情况下,我们取参数的值都应该去使用#{};但是,原生jdbc不支持占位符的地方,我们就可以使用${}进行取值, 比如分表/order排序/按照年份分表拆分:
" select * from ${year} where xxx;"
" select * from ${year}_salary where xxx;",year取2016/2017/2018等等;
" select * from tbl_employee order by ${f_name};".