MyBatis #{} 和${}的区别

MyBatis 在对实体类配置映射文件中时 传递参数可以有 #{ } 和${ }两种 那么这两种到底有什么区别呢,


首先 来看看这两种方式传参后SQL语句的编译结果 (传入参数‘赵’)

1、#{ }形式:

select * from smbms_user where 1=1 and userName like concat ('%',#{userName},'%')

编译结果:

DEBUG - ==>  Preparing: select * from smbms_user where 1=1 and userName like concat ('%',?,'%') 
DEBUG - ==> Parameters: 赵(String)

2、${ }形式:

select * from smbms_user where 1=1 and userName like ('%${userName}%')

编译结果: 

DEBUG - ==>  Preparing: select * from smbms_user where 1=1 and userName like ('%赵%') 
DEBUG - ==> Parameters:

来看这两个语句的编译结果  
#{ }形式传入参数 编译后参数时一个一?为占位符的语句,然后在赋值,替换占位符。
${ }形式传入参数,编译时就已经吧值放到了语句的参数位置,然后执行语句。
由此我们可以看出,#{ }形式的传参是安全的,可以有效的避免SQL注入。  
    ${ }形式的传参是不安全的,容易被SQL注入。


大家还会看到一个问题,这两个映射文件的SQL语句不只是这点不同吧 ?

没错 还有这里 concat 这个关键字 
MySQL中 concat函数用于将多个字符串连接成一个字符串
例如 

select CONCAT('a','b','c')

运行结果是  abc

select CONCAT('a',b,'c')
运行则会报错

显然:上面的语句参入参数(赵)后的编译 是不同的,如果都用concat函数的话

select * from smbms_user where 1=1 and userName like concat ('%',#{userName},'%')

#{ } 编译形式 结果为
DEBUG - ==>  Preparing: select * from smbms_user where 1=1 and userName like concat ('%',?,'%') 
DEBUG - ==> Parameters: 赵(String)
MyBatis 的解释为:?为一个占位符,会被一个varchar类型的值替代,替代后的结果为
select * from smbms_user where 1=1 and userName like concat ('%','赵 ','%') 
  执行concat函数后为:
select * from smbms_user where 1=1 and userName like concat ('%赵%')
 这样的语句在执行是没有问题的。

如果是这样呢??
select * from smbms_user where 1=1 and userName like concat ('%',${userName},'%')

${ }形式 编译结果为
DEBUG - ==>  Preparing: select * from smbms_user where 1=1 and userName like concat ('%',赵,'%') 
DEBUG - ==> Parameters: 

  直接把参数放到了入参的位置上,然后交给Mysql去解释,结果是这样的:
[SQL]select * from smbms_user where 1=1 and userName like concat ('%',赵,'%') 
[Err] 1054 - Unknown column '赵' in 'where clause'

 报错,原因是,不存在列‘赵’。    mysql 无法没有吧 ‘赵’ 当做 concat的参数, 而是当做列来处理,所以执行报错

因此,#{ } 形式传参 和${ }传参还是有差异的  尤其是当使用参数做模糊查询时。
有句话很经典 ,一切以运行结果为准。语句的解释权在jar里,我们可以通过执行后的结果,来看错误。



菜鸟的见解,欢迎交流


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值