[Java MyBatis] #{}与${}的使用与区别(详细)


前言

        最近在学习MyBatis遇到不会的就找博客,学到这发现这部分内容有所欠缺。虽然在这条路上我还是个新手,但每次遇到问题最常帮助我的都是这些陌生人的博客,这次就由我来吧。欢迎转载,请标明出处。有名字就更好了


#{}与${}的使用

#{ } 是占位符填充,如下当我们执行sql语句时会将sql语句中的 #{id} 替换成 ?号

UserDao.java 接口文件:

 User queryUserByUsername(@Param("username") String username);

UserDaoMapper.xml 映射文件:

 <select id="queryUserByUsername" resultMap="user_resultMap">
	 select id,username,password,gender,regist_time
	 from t_user
	 where username=#{username}
 </select>

执行后的sql语句:

	select id,username,password,gender,regist_time
    from t_user
    where username=?

${}是字符串拼接,多数情况下使用与#{}没区别,但是有下面几点要注意:

  1. 如果这个列是字符类型,我们要加引号,如where username=’${username}’
  2. 如果传入参数是简单类型像是数字、字符串等要在UserDao.java中加@Param(“username”)否则${}取值会有问题
  3. 如果是一个引用类型的实例对象参数,那我们可以不加,如:
    User queryUserByUsername(@Param (“username”) User user);

存在问题

使用${}当拼接sql片段时,有sql注入风险,外界参数会改变原有sql的语义,如:

 //sql注入
 String username = "zhangsan' or '1'='1";

注入后的sql语句:

 select id,username,password,gender,regist_time
 from t_user
 where username='zhangsan' or '1'='1'

这就导致了哪怕你数据库中没有这个用户名也能成功查询到数据。而使用 #{ } 它会将sql语义过滤,将 zhangsan’ or ‘1’='1 当成一个普通字符串,可以规避sql注入的风险。所以原则上能不用sql拼接就不用sql拼接,那为什么还要有 ${ } 的存在呢?是因为在有些场景中 #{ } 不能使用,如我们要给查询到的数据进行排序

 String rule="desc";
 String sql="select * from t_user order by id ?";

当我们在占位符上填充desc时,会导致sql语句语法出错,这就涉及了占位符的使用原则

 //原则:填充数据,要和列相关
 select * from t_user where id=?
 inseret into t_user values(?,?,?)
 update t_user set username?,password=?

显然desc与列无关,就会导致报错

小技巧

MyBatisTest.java 测试方法

	@Test
	public void test(){
        UserDao mapper = MyBatisUtil.getMapper(UserDao.class);
        Integer sig=0;   //0:desc  1:asc
        if(sig==0){
        	mapper.queryUserUsers("desc");
        }else{
			mapper.queryUserUsers("asc");	
		} 
	}        

使用 ${ } 拼接sql片段的时候,用户传的内容只是一个依据,我们可以通过这个依据进行判断,这时我们就能拼接自己定义的内容,而不是用户输入的内容。这样即使我们拼接了语句也不会被注入,所以这是一个使用 ${ } 时非常重要的小技巧


优势与劣势

优势劣势
${ } 字符串拼接可以随意拼接有sql注入的风险
#{ } 占位符规避sql注入风险要和列相关的位置才可以使用

总结

        当我们想要去取值时,能用 #{ }就尽量用 #{ },什么时候不能用 #{ }呢?如果这个位置不是为某个列做值的相关,而是要在某些sql片段上进行动态填充,那我们必须用 ${ }来取值。


资料参考

https://www.bilibili.com/video/BV1gC4y1p7z2?p=845

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值