Mybatis中#{}和${}的区别是什么

举报
辰兮 发表于 2022/03/23 01:03:23 2022/03/23
【摘要】 【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行! 博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、...

【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行!

博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、数据库、项目案例等相关知识点总结,感谢你的阅读和关注,希望我的博客能帮助到更多的人,分享获取新知,大家一起进步!

吾等采石之人,应怀大教堂之心,愿你们奔赴在各自的热爱中…


一、文章序言

开局分享一波干货欢迎打卡!

在这里插入图片描述

SSM框架常考面试题汇集

JAVA常见基础面试题汇集


在Mybatis面试中常涉及到关于#{}和${}的区别

1、#{}是预编译处理,$ {}是字符串替换。

2、MyBatis在处理#{}时,会将SQL中的#{}替换为?号,使用PreparedStatement的set方法来赋值;MyBatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。

3、使用 #{} 可以有效的防止SQL注入,提高系统安全性。


二、业务场景

select * from user where id= "1";

  
 
  • 1

上述 sql 中,我们希望对应的id可以变化,根据不同的id查询出不同的学生,在 Mapper.xml文件中使用如下的 sql 可以实现动态传递参数 id:

关于#的使用

select * from user where  id= #{id}; 

  
 
  • 1

当传来参数id=2的时候,解析为:

select * from user where id= ?;

  
 
  • 1

关于$的使用

select * from user where  id= ${id}; 

  
 
  • 1

当传来参数id=2的时候,解析为:

select * from user where id = "2";

  
 
  • 1

小结: ${ } 变量的替换阶段是在动态 SQL 解析阶段,而 #{ }变量的替换是在 DBMS 中。

案例测试:

   <select id="getUsersByWhere" resultType="com.example.cwgl.entity.UserInfo" parameterType="com.example.cwgl.entity.UserInfo">
        SELECT *, rolename FROM user left join role on role.roleid = user.roleid
        <where>
            <if test="data.username!=null">(username = #{data.username} or realname = #{data.realname})</if>
            <if test="data.roleid!=null and data.roleid!=-1">and user.roleid >= #{data.roleid}</if>
            <if test="data.houseid!=null and data.houseid.length!=0">and houseid = #{data.houseid}</if>
        </where>
        order by user.roleid asc
        limit #{beginIndex},#{pageSize}
    </select>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

当我们使用#的时候,很明显可以看到MyBatis在处理#{}时,会将SQL中的#{}替换为?号


三、补充讲解

$ 符号一般用来当作占位符

#{}是sql的参数占位符,Mybatis会将sql中的#{}替换为?号,在sql执行前会使用PreparedStatement的参数设置方法,按序给sql的?号占位符设置参数值。

预编译的机制。预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。

<select id="insertUser" parameterType="User">
	INSERT INTO users(name,age) values(#{name},#{age})
</select>

  
 
  • 1
  • 2
  • 3

${}的使用场景:先在配置文件中定义好变量,再在conf.xml中如下使用:

<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbcDriver}" />
<property name="url" value="${jdbcUrl}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

我们最开始接触Java时候SSM项目配置数据库连接就用户的上述方式

${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如${jdcDriver}会被静态替换为com.mysql.jdbc.Driver。

  
 
  • 1

在某些特殊场合下只能用${},不能用#{}。例如:在使用排序时ORDER BY ${id},如果使用#{id},则会被解析成ORDER BY “id”,这显然是一种错误的写法。

#方式能够很大程度防止sql注入;$方式无法防止Sql注入。

一般能用#的就别用$。MyBatis排序时使用order by 动态参数时需要注意,用$而不是#。

  
 
  • 1

非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤️ 分享👥 留言💬thanks!!!

2021年2月22日20:14:57 愿你们奔赴在自己的热爱里!

文章来源: blessing.blog.csdn.net,作者:辰兮要努力,版权归原作者所有,如需转载,请联系作者。

原文链接:blessing.blog.csdn.net/article/details/113953821

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。