温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java mybatis如何动态写sql

发布时间:2026-09-02 18:33:22 来源:亿速云 阅读:94 作者:小樊 栏目:编程语言

MyBatis 中,“动态写 SQL”通常指 根据条件动态拼接 SQL,MyBatis 提供了多种机制来实现,下面按常见程度和使用场景给你系统讲一下。


一、最常用:XML 中的动态 SQL 标签

1️⃣ <if> 条件拼接

<select id="selectUser" resultType="User">
  SELECT * FROM user
  WHERE 1=1
  <if test="name != null">
    AND name = #{name}
  </if>
  <if test="age != null">
    AND age = #{age}
  </if>
</select>

✅ 条件满足才拼接 SQL


2️⃣ <where> 自动处理 AND / OR

避免手写 1=1

<select id="selectUser" resultType="User">
  SELECT * FROM user
  <where>
    <if test="name != null">
      AND name = #{name}
    </if>
    <if test="age != null">
      AND age = #{age}
    </if>
  </where>
</select>

✅ 自动去掉多余 AND


3️⃣ <choose> / <when> / <otherwise>(类似 switch)

<select id="selectUser" resultType="User">
  SELECT * FROM user
  <where>
    <choose>
      <when test="type == 'A'">
        AND type = 'A'
      </when>
      <when test="type == 'B'">
        AND type = 'B'
      </when>
      <otherwise>
        AND status = 1
      </otherwise>
    </choose>
  </where>
</select>

4️⃣ <foreach> 循环(IN 查询)

<select id="selectByIds" resultType="User">
  SELECT * FROM user
  WHERE id IN
  <foreach collection="ids" item="id" open="(" close=")" separator=",">
    #{id}
  </foreach>
</select>

调用:

List<User> selectByIds(@Param("ids") List<Integer> ids);

5️⃣ <set> 动态更新

<update id="updateUser">
  UPDATE user
  <set>
    <if test="name != null">name = #{name},</if>
    <if test="age != null">age = #{age},</if>
  </set>
  WHERE id = #{id}
</update>

✅ 自动去掉多余逗号


6️⃣ <trim> 更灵活的控制

<trim prefix="WHERE" prefixOverrides="AND | OR">
  <if test="name != null">
    AND name = #{name}
  </if>
</trim>

二、注解方式(@SelectProvider 等)

适合 SQL 变化非常复杂 的场景

1️⃣ 使用 Provider 类

@SelectProvider(type = UserSqlProvider.class, method = "listUser")
List<User> listUser(User user);
public class UserSqlProvider {
  public String listUser(User user) {
    return new SQL(){{
      SELECT("*");
      FROM("user");
      if (user.getName() != null) {
        WHERE("name = '" + user.getName() + "'");
      }
    }}.toString();
  }
}

⚠️ 注意 SQL 注入风险,推荐用条件拼 SQL + 参数


三、MyBatis-Plus(最推荐)

如果你用的是 MyBatis-Plus,动态 SQL 非常简单:

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like(name != null, "name", name);
wrapper.eq(age != null, "age", age);

✅ 自动防注入
✅ 代码级动态 SQL


四、真实 SQL 片段拼接(高级)

<sql> + <include>

<sql id="userColumns">
  id, name, age
</sql>

<select id="selectUser">
  SELECT <include refid="userColumns"/>
  FROM user
</select>

五、什么时候用哪种?

场景 推荐方式
普通条件查询 XML 动态 SQL
多表复杂 SQL XML + <foreach>
SQL 极端动态 Provider
快速开发 MyBatis-Plus
公共 SQL 片段 <sql>

如果你愿意,可以告诉我:

  • ✅ 用的是 MyBatis 还是 MyBatis-Plus
  • ✅ 是 XML 还是 注解
  • ✅ 具体业务场景(查询 / 更新 / IN / 分页)

我可以直接帮你写一份可运行的示例。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI