引入
我们来做个根据id,name查询学生信息的查询。
分别用$和#的方式。
用#做查询
Student findByIdAndName(@Param("id") String id, @Param("name") String name);
<select id="findByIdAndName" resultType="com.example.model.Student" >
select * from student
where s_id = #{id} and s_name = #{name}
</select>
@Test
public void test() {
Student students = studentMapper.findByIdAndName("01","张三");
}
打印sql语句查看(重点看参数):
==> Preparing: select * from student where s_id = ? and s_name = ?
==> Parameters: 01(String), 张三(String)
<== Columns: s_id, s_name, s_birth, s_sex
<== Row: 01, 张三, 1990-01-01, 男
<== Total: 1
用$做查询
<select id="findByIdAndName" resultType="com.example.model.Student" >
select * from student
where s_id = ${id} and s_name = #{name}
</select>
打印sql语句查看(重点看参数):
==> Preparing: select * from student where s_id = 01 and s_name = ?
==> Parameters: 张三(String)
<== Columns: s_id, s_name, s_birth, s_sex
<== Row: 01, 张三, 1990-01-01, 男
<== Total: 1
注意看两种方式的sql语句,会发现用#传入参数会用?来替换,而$直接把值显示出来做sql的拼接。
那我们可以得出以下结论:
#:参数都是预编译后设置进去的,用?来替换,安全,防止sql注入。
$: 不是参数预编译,而是直接sql拼接。
那么$就没有使用场景了吗?
如果我们有这么一个需求:要分别根据传入的表名做查询,动态的获取数据。
先从#试试。
Student findByTableName(String tableName);
<select id="findByTableName" resultType="com.example.model.Student" >
select * from #{tableName}
</select>
@Test
public void test() {
Student students = studentMapper.findByTableName("student");
}
代码看起来好像没什么问题的亚子…那我们一运行…
报错了…
表名等不能用#的方式去获取。
我们试试走$方式,成功打印出数据。
==> Preparing: select * from student
==> Parameters:
<== Columns: s_id, s_name, s_birth, s_sex
<== Row: 01, 张三, 1990-01-01, 男
<== Row: 02, 钱电, 1990-12-21, 男
<== Row: 03, 孙风, 1990-05-20, 男
<== Row: 04, 李云, 1990-08-06, 男
<== Row: 05, 周梅, 1991-12-01, 女
<== Row: 06, 吴兰, 1992-03-01, 女
<== Row: 07, 郑竹, 1989-07-01, 女
<== Row: 08, 王菊, 1990-01-20, 女
<== Total: 8