MyBatis 笔记——动态参数与 `#` 和 `$` 的使用

MyBatis 简介

MyBatis 是一个支持定制化 SQL、存储过程和高级映射的持久层框架。它通过将 SQL 映射为 Java 方法,让开发人员更容易地控制数据库操作。

在 MyBatis 中,动态 SQL 是一种重要的功能,可以在运行时动态地生成 SQL 语句。常常用于条件查询、批量更新等场景。
(虽然plus对于简单的单表查询已经不需要再写sql了,但是实际开发中避免不了多表查询)


1. 动态 SQL 简介

在 MyBatis 中,动态 SQL 允许我们在查询时根据条件动态生成 SQL 语句。动态 SQL 可以通过 等标签来实现。

常见的动态 SQL 标签:

  • :根据条件判断是否包含某个 SQL 片段。
  • :类似于 Java 中的 switch,用于多个条件判断。
  • :用于遍历集合,生成动态 SQL。
  • :可以用于去除 SQL 中多余的符号(如 ,AND 等)。

2. 动态参数:#$

在 MyBatis 中,#$ 是两种常用的参数占位符,它们在 SQL 查询中有不同的作用。

2.1 # 占位符:安全的参数绑定(防止 SQL 注入)

作用:将参数绑定到 SQL 查询中,并自动转义值。它会将参数值用适当的方式包装,并且不会直接拼接到 SQL 中,从而避免了 SQL 注入的风险。

示例:
<select id="findUserById" resultType="User">
  SELECT * FROM users WHERE id = #{userId};
select>
说明:
  • #{userId} 会自动绑定 userId 参数并进行类型转换或转义。
  • 优点:避免 SQL 注入、避免拼接 SQL。

2.2 $ 占位符:直接拼接参数(不做转义)

作用:将参数的值直接拼接到 SQL 中,不会做任何转义处理。这种方式容易引发 SQL 注入漏洞,应谨慎使用。

示例:
<select id="findUserByName" resultType="User">
  SELECT * FROM users WHERE name = ${name};
select>
说明:
  • ${name} 直接将 name 参数的值拼接到 SQL 中,不会进行任何转义。
  • 警告:如果传入的参数包含特殊字符,可能导致 SQL 注入风险。

3. #$ 的区别

特性 # 占位符 $ 占位符
作用 自动转义、避免 SQL 注入 直接拼接参数,存在 SQL 注入风险
使用场景 适用于所有的查询、更新等 仅在必要时使用,如 SQL 语句中拼接列名或表名等
安全性

结论:

  • 推荐使用 # 占位符,它能避免 SQL 注入问题。
  • 只有在非常明确的场景下,如拼接表名、列名时,才能使用 $ 占位符。

4. 动态 SQL 示例

4.1 使用 标签动态生成查询条件

<select id="findUsers" resultType="User">
  SELECT * FROM users
  WHERE 1=1
  <if test="name != null">AND name = #{name}if>
  <if test="age != null">AND age = #{age}if>
select>
说明:
  • 如果 name 不为 null,则生成 AND name = #{name}
  • 如果 age 不为 null,则生成 AND age = #{age}

4.2 使用 标签

<select id="findUsersByCondition" resultType="User">
  SELECT * FROM users
  <where>
    <choose>
      <when test="age != null">AND age = #{age}when>
      <when test="name != null">AND name = #{name}when>
      <otherwise>AND status = 'ACTIVE'otherwise>
    choose>
  where>
select>
说明:
  • 根据条件,选择使用 agename 或默认的 status

4.3 使用 标签遍历集合

<select id="findUsersByIds" resultType="User">
  SELECT * FROM users
  WHERE id IN
  <foreach item="id" collection="ids" open="(" close=")" separator=",">
    #{id}
  foreach>
select>
说明:
  • 通过 循环遍历 ids 集合,将每个 id 作为参数插入 IN 子句中。

5. 动态 SQL 和参数的结合使用

动态 SQL 和 #$ 占位符结合使用,可以在运行时根据不同条件生成不同的 SQL 查询。

5.1 示例:动态 SQL 和动态参数

<select id="findUsersByCondition" resultType="User">
  SELECT * FROM users
  <where>
    <if test="name != null">AND name = #{name}if>
    <if test="age != null">AND age = #{age}if>
    <if test="status != null">AND status = #{status}if>
  where>
select>
说明:
  • 通过动态条件生成 SQL,在查询时根据输入的参数来决定是否添加某个查询条件。

6. 总结

配置方式 使用场景 安全性
# 占位符 适用于所有参数传递 高,避免 SQL 注入
$ 占位符 仅在特殊情况下使用(如表名、列名等) 低,容易引发 SQL 注入问题

小贴士:

  • 优先使用 # 占位符,它能自动进行参数转义,避免 SQL 注入。
  • 仅在必须拼接表名、列名等动态内容时,使用 $ 占位符,但要小心 SQL 注入风险。

你可能感兴趣的:(SQL学习笔记,java,数据库,开发语言)