您的位置:首页 > 教育 > 培训 > 安卓android软件_邯郸兄弟建站_百度关键词刷搜索量_创建自己的网页

安卓android软件_邯郸兄弟建站_百度关键词刷搜索量_创建自己的网页

2025/3/24 13:54:51 来源:https://blog.csdn.net/2302_81090306/article/details/146433779  浏览:    关键词:安卓android软件_邯郸兄弟建站_百度关键词刷搜索量_创建自己的网页
安卓android软件_邯郸兄弟建站_百度关键词刷搜索量_创建自己的网页

目录

  • 一、前言
  • 二、 `#{}` 和`${} `的使用方法和区别
    • 2.1 `#{}`使用方法
    • 2.2 `${}`使用方法
    • 2.3`#{}` 和 `${}` 的主要区别
    • 2.4使用建议
  • 三、总结

一、前言

在 MyBatis 中,#{}${} 都用于在 SQL 语句中绑定参数,但它们在具体实现和安全性方面有所不同。理解它们的区别对于编写高效且安全的 MyBatis 映射文件非常重要。这篇文章主要讲一下他们的使用和区别。


数据库数据信息:
在这里插入图片描述

二、 #{}${} 的使用方法和区别

2.1 #{}使用方法

在 MyBatis 中,#{} 用于绑定参数值,将其直接插入到 SQL 语句中。它不进行任何类型转换,适用于简单类型的参数绑定,如字符串、整数等。

示例:

UserInfoMapper.xml 文件

    <select id="selectById" resultType="java.lang.Integer">select * from user_info where id=#{id}</select>

UserInfoMapperXML接口

  List<UserInfo> selectById(Integer id);

测试类

  @Testvoid selectById() {userInfoMapperXML.selectById(3).stream().forEach(x-> System.out.println(x));}

运行结果:
在这里插入图片描述

作用解析:

  • #{id} 会将参数值直接替换到 SQL 语句中。
  • 我们输⼊的参数并没有在后面拼接,id的值是使用 ? 进行占位. 这种SQL 我们称之为"预编译SQL"。
  • 适用于不需要类型转换的简单参数。

2.2 ${}使用方法

我们把上面的UserInfoMapper.xml 文件改一下,把#{}改成${}再观察打印日志。

UserInfoMapper.xml 文件:

 <select id="selectById" resultType="com.sliqvers.model.UserInfo">select * from user_info where id=${id}</select>

观察运行结果日志:
在这里插入图片描述
可以看到, 这次的参数是直接拼接在SQL语句中了.

2.3#{}${} 的主要区别

再举一个例子来对比一下#{}${}的区别。
#{}

UserInfoMapperXML接口

List<UserInfo> selectByusername(String username);

UserInfoMapper.xml 文件

<select id="selectByusername" resultType="com.sliqvers.model.UserInfo">select * from user_info where username=#{username}</select>

测试类

  @Testvoid selectByusername() {userInfoMapperXML.selectByusername("Bob").stream().forEach(x-> System.out.println(x));}

运行结果:
在这里插入图片描述

我们再来看:
${}

我们把UserInfoMapper.xml 文件稍微改一下,其他的不变。

<select id="selectByusername" resultType="com.sliqvers.model.UserInfo">select * from user_info where username=${username}</select>

我们再来看运行结果:
在这里插入图片描述
可以看到这个报错了,因为username是字符串类型,这个Bob少了两个引号。

我们把这个引号加上去:

<select id="selectByusername" resultType="com.sliqvers.model.UserInfo">select * from user_info where username='${username}'</select>

运行结果:
在这里插入图片描述
可以看到问题得以解决。

综上可以得出他们的区别.

#{} 使用的是预编译SQL, 通过 ? 占位的方式, 提前对SQL进行编译, 然后把参数填充到SQL语句中. #{} 会根据参数类型, 自动拼接引号 ‘’ .
${} 会直接进行字符替换, ⼀起对SQL进行编译. 如果参数为字符串, 需要加上引号 ‘’ .

特性#{}${}
参数处理将参数值直接替换为字符串,不进行类型转换对参数值进行 JDBC 类型转换
安全性旧版本可能存在 SQL 注入风险,新版本默认安全旧版本可能存在 SQL 注入风险,新版本默认安全
使用场景适用于简单类型的参数绑定适用于需要类型转换的参数绑定或动态 SQL 场景
示例select * from users where username = #{username};select * from users where birthday = ${birthday};

提出问题:
从上面的例子中, 可以得出结论:${}会有SQL注入的风险, 所以我们尽量使用#{}完成查询。
既然如此, 是不是 ${} 就没有存在的必要性了呢?

当然不是⼀些场景,#{}不能完成, 比如 排序功能, 表名, 字段名作为参数时, 这些情况需要使用${}

${}的使用场景:
在这里插入图片描述

设计一个排序查询:

UserInfoMapperXML.java 文件:

  List<UserInfo> selectBysort(String sort);

UserInfoMapper.xml文件

 <select id="selectBysort" resultType="com.sliqvers.model.UserInfo">select * from user_info order by age #{sort}</select>

测试类:

   @Testvoid selectBysort() {userInfoMapperXML.selectBysort("asc").stream().forEach(x-> System.out.println(x));}

运行结果:
在这里插入图片描述
可以看到报错了。因为此处 sort 参数为String类型, 但是SQL语句中, 排序规则是不需要加引号 ‘’ 的。
我们把#{sort} 换成${}然后看一下运行结果:

  <select id="selectBysort" resultType="com.sliqvers.model.UserInfo">select * from user_info order by age ${sort}</select>

在这里插入图片描述
运行成功了。


模糊查询虽然${}可以完成, 但因为存在SQL注入的问题,所以通常使用mysql内置函数concat来完成。

设计一个like查询:

UserInfoMapperXML.java 文件:

 List<UserInfo> selectBylike(String like);

UserInfoMapper.xml文件

  <select id="selectBylike" resultType="com.sliqvers.model.UserInfo">select * from user_info where username like `${like}%`</select>

测试类:

   @Testvoid selectBysort() {userInfoMapperXML.selectBysort("asc").stream().forEach(x-> System.out.println(x));}

使用#{}会报错,使用${}可以运行但是不安全,存在SQL注入的问题,所以使用MySQL的内置函数concat()来进行。

UserInfoMapper.xml文件

 <select id="selectBylike" resultType="com.sliqvers.model.UserInfo">select * from user_info where username like concat('${like}%')</select>

运行结果:

在这里插入图片描述


2.4使用建议

何时使用 #{}

  • 当需要绑定的参数是简单类型,如字符串、整数。
  • 当不需要对参数进行类型转换时。

何时使用 ${}

  • 当需要对参数进行类型转换时,如日期、Blob 类型。
  • 当需要动态生成 SQL 语句时,例如根据条件添加 WHERE 子句。

安全注意事项:

  • 无论使用 #{} 还是 ${},都要确保参数值已经过适当的过滤和验证,以防止 SQL 注入。
  • 依赖 MyBatis 的预编译语句和类型转换功能,增强安全性。

三、总结

  • #{}${} 都用于 MyBatis 的参数绑定,但 #{} 不涉及类型转换,而 ${} 会进行类型转换。
  • #{} 适用于简单类型的参数绑定,${} 适用于复杂类型或需要类型转换的场景。
  • 在使用时,重点关注参数的安全性,确保参数已经过适当的验证和过滤。
    通过合理选择 #{}${},可以编写出高效、安全的 MyBatis 映射文件,提升开发效率。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com