关于#{}:
先编译sql语句,再给占位符传值,底层是PreparedStatement实现。可以防止sql注入,比较常用。
关于${}:
先进行sql语句拼接,然后再编译sql语句,底层是Statement实现。存在sql注入现象。
需要使用${}的几种情况:
1、在需要进行sql语句"关键字"拼接的情况下才会用到。
2、拼接数据库表名的情况下需要使用。(此时需要先拼接后编译)
在实际开发中有些数据量非常大,需要分表存储,然后分表查询,比如:日志信息表基本上是每天一张表,现有多张日志信息表:log_20230101、log_20230102、log_20230103…
此时需要查询日志信息就需要在sql语句中在log后面拼接时间信息,这种情况之下就需要使用${}进行先拼接后编译
3、批量删除:
批量删除的sql语句有两种写法:
1)使用or:delete from student where id=1 or id=2 or id=3;
2)使用in:delete from student where id in(1,2,3);
在studentMapper.xml文件中批量删除的sql语句写法是:
<delete id="deleteByIds">
delete from student where in(${ ids}); 而不能写成:delete from student where in(#{ ids});
</delete>
4、模糊查询:
需求:根据汽车品牌进行模糊查询
通用查询语句:
select * from t_car where brand like '%比亚迪%';
select * from t_car where brand like '%长城%';
在carMapper.xml文件中该模糊查询的sql语句写法是:
第一种方案:
<select id="deleteByIds" resultType="com.yjg.mybatis.pojo.car">
delete from t_car where brand like '%${brand}%';
</select>
第二种方案:使用concat()函数,这是mysql数据库中的一个函数,专门用来做字符串拼接的
<select id="deleteByIds" resultType="com.yjg.mybatis.pojo.car">
delete from t_car where brand like concat('%',#{brand},'%'); <!-- #号花括号外面没有单引号 -->
</select>
第三种方案:
<select id="deleteByIds" resultType="com.yjg.mybatis.pojo.car">
delete from t_car where brand like concat('%','${brand}','%'); <!-- 美元符号花括号外面需要有单引号 -->
</select>
第四种方案:
<select id="deleteByIds" resultType="com.yjg.mybatis.pojo.car">
delete from t_car where brand like "%"#{brand}"%";
</select>
比如:在查询某班全体学生并按照姓名按照升序/降序排列的sql语句中,当需要传入关键字asc"或"desc"的时候需要使用${}而不能使用#{},像这种需要传入关键字的sql语句需要使用${},其它情况需要使用#{},用来防止出现sql注入现象。
注意:使用#{}来传值,在sql语句中传入的值带有引号,为此不能使用#{}来传入关键字。