#{}和${}的用法和区别

举报
多米诺的古牌 发表于 2022/08/28 19:32:37 2022/08/28
【摘要】 在Java编程过程中,我们肯定是少不了和SQL打交道的,无论的是查询的SQL还是新增、修改、删除的SQL我们都会传对应数据的不断变化的参数值,我们不能每次传值就去修改SQL,需要一个占位符来接收这个可变的参数值,这样在Mapper.xml映射文件中,我们经常会使用#{属性名} 来作为SQL语句的占位符,来映射Sql需要的实际参数值。

​1.#{}的用法

在Java编程过程中,我们肯定是少不了和SQL打交道的,无论的是查询的SQL还是新增、修改、删除的SQL我们都会传对应数据的不断变化的参数值,我们不能每次传值就去修改SQL,需要一个占位符来接收这个可变的参数值,这样在Mapper.xml映射文件中,我们经常会使用#{属性名} 来作为SQL语句的占位符,来映射Sql需要的实际参数值。

1.1 一个参数的占位符使用

如果只有一个参数我们只需要在对应的字段后面跟上#{属性值}就可以接收传递过来的参数值,也就是说#{}起到的作用就是一个预编译的占位符的作用,运行代码的时候会编译成 ?,但这只适用于只有一个参数的情况,而且这种一个参数的情况#{id}中的id可以写成任何字符串,比如#{aaa}

    select * from test where id=#{id}

1.2 多个参数的占位符使用

1.2.1 按照参数的顺序,通过使用自然序号对应所传递的参数来对应标注出传递的参数位置,这种方法需要对代码和业务逻辑比较熟悉,因为是使用自然序号来进行标注参数的位置的,所以稍微错位就会造成整个语句的混乱,所以不太推荐这种形式。

    select * from test where id=#{0} and name=#{1}
1.2.2 跟第一种比较类似,只是改为按照顺序通过param1、param2来进行标注参数的位置,这种形式跟第一种比较相似,如果标注的稍微有错位的情况也会造成整个语句的混乱,所以也不是很推荐这种形式的编码。
    select * from test where id=#{param1} and name=#{param2}
1.2.3 利用接口Mapper中对应的参数,必须保证xml和接口Mper中的参数名称保持一致,这样对应起来代码的可读性就增加了很多,而且也不容易出现错位造成整个语句混乱这种错位,因为是接口Mapper中的参数每个都必须一一对应到sql中才能使用,所以准确率肯定会提高很多,因此推荐这种使用占位符#{}的方法来进行使用。
public interface TestMapper {
    public Test getUserByNameAndAge(@Param("id") Integer id, @Param("name") String name);
} 
   select * from test where id=#{id} and name=#{name}

2.${}的用法

${}的用法和#{}的用法都是占位符的作用,但是它们的不同在于#{}会被编译成?,而${}则会被原样输出,并且用在参数上的时候,需要使用param注解。

3.#{}和${}的区别

#{}会对SQL进行预编译会将占位符的位置编译成?,${}是做sql拼接会原样输出,会有SQL注入的隐患。#{}不需要关注数据类型,MyBatis会自动实现数据类型的转换; ${} 必须自己判断数据类型(需要再接口Mapper中使用@param注解进行标注),两者相同之处都是占位符的作用,都是支持@param注解。因为${}有SQL注入隐患,所以我们一般在Sql中使用#{}来进行参数的占位。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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