概述
在我们开始使用mapper配置文件来进行编写SQL语句的时候,我们一直使用#{}来进行传参,我们传入一个对象,通过自动获取对象的属性来进行与SQL语句进行交互,其实在传参的时候,还有一种方式,就是:${},那么我们来说一下他们的区别。
#{}与${}的区别和使用选择
#{}: 会把参数的位置使用”?”做占位符,执行SQL的时候才会替换”?”的值
我们在使用Mybatis时,里面封装的进行与数据库进行交互的方法默认的是使用PrepareStatement,进行预编译,然后再把参数通过占位符?来执行SQL语句,而这种情况大多是对于insert,update的插入和修改值以及where后面进行判断的条件的参数,而这些内容都会有一个特点,是对数据库中的数据进行交互,大部分时间是需要加上一对单引号来进行区分其他语句中的关键词。
我们来执行一个插入语句:
#{}在把参数放入占位符的时候,会自动的给外层加上一对单引号。
然后我们把同样的语句放入数据库中再次执行一次:
我们知道里面的age,salary等属性是不用加单引号的,但是加了单引号也不会报错,也会正常的进行插入。
${}: 直接把参数中的值作为SQL的一部分来执行
我们进行插入代码的修改 把#换成$:
<insert id="insertEmp" useGeneratedKeys="true" keyColumn="e_id" keyProperty="id">
insert into emp (e_name,e_age,e_birthday,e_salary) values (${name},${age},${birthday},${salary})
</insert>
再次进行测试:
如果把这句话放入数据库是什么情况呢?
我们会发现,这里面的字符串属性已经和数据库对不上了,如果不加单引号,那么就会报错。
那么我们又想到了SQL语句注入问题,我们模拟一个登陆操作。
<select id="findEmpByNameAndAge3" resultMap="useResultMap">
select e_id,e_name,e_age,e_birthday,e_salary from emp where e_name = #{name} and e_age = #{age}
</select>
我们可以看到因为年龄参数不对应,所以没有查到,也就相当于无法登陆。
但是我们如果把查询语句中的#改为$
<select id="findEmpByNameAndAge3" resultMap="useResultMap">
select e_id,e_name,e_age,e_birthday,e_salary from emp where e_name = ${name} and e_age = #{age}
</select>
测试语句改为:
@Test
public void testfindEmpByNameAndAge3() {
EmpService service = new EmpServiceImpl();
Emp emp = service.findEmpByNameAndAge3("'佐助' or '1' = '1'",100099);
System.out.println(emp);
}
再次测试:
成功了,所以用了$,还是会有注入问题。
那么${}有什么作用呢?
我们进行一个排序查询操作:
//根据年龄字段进行排序输出
//mapper接口方法
List<Emp> findAllEmpOrder(@Param("column") String column);
//查询语句
<select id="findAllEmpOrder" parameterType="string" resultMap="useResultMap" >
select e_id,e_name,e_age,e_birthday,e_salary from emp order by #{column} desc
</select>
//service实现类方法
@Override
public List<Emp> findAllEmpOrder(String column) {
SqlSession sqlSession = MybatisUtil.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> list = mapper.findAllEmpOrder(column);
return list;
}
//测试方法
@Test
public void testfindAllEmpOrder(){
EmpService service = new EmpServiceImpl();
List<Emp> list = service.findAllEmpOrder("e_age");
for(Emp emp : list){
System.out.println(emp);
}
}
结果:
并没有进行年龄排序。
我们再把#换成$其他方法不变,再次进行查询
因为在SQL查询语句中是需要:
select e_id,e_name,e_age,e_birthday,e_salary from emp order by e_age desc
在order by 字段后面的内容是不需要用单引号引起来的。
这也是${}的一个作用。
区别
我们发现非常重大的区别,就是传入的信息是否用单引号引起来还能够发挥作用。
还能够的就使用#{} ,不能够的就使用${}
这也就是两者用来判断使用哪个的重要条件和最快捷的实验的方式
最后
以上就是紧张萝莉为你收集整理的#{}与${}的区别和使用选择#{}与${}的区别和使用选择的全部内容,希望文章能够帮你解决#{}与${}的区别和使用选择#{}与${}的区别和使用选择所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复