Mybatis 动态 SQL 写法全攻略:2025 最新案例解析与常见问题解答

2025-06-12| 1045 阅读
Mybatis 动态 SQL 写法全攻略:2025 最新案例解析与常见问题解答

在 Java 持久层开发中,Mybatis 的动态 SQL 功能堪称 “神器”,它能让开发者根据不同条件灵活拼接 SQL 语句,告别繁琐的字符串拼接和硬编码。特别是 2025 年的最新实践中,动态 SQL 的应用场景和优化策略又有了新的突破。今天咱们就来深入聊聊这事儿,从核心标签到实战案例,再到常见问题,一次性给你整明白。

? 动态 SQL 核心标签深度解析


Mybatis 的动态 SQL 主要依赖一系列标签来实现条件判断、循环遍历和 SQL 片段复用。这些标签就像 “积木”,能组合出各种复杂的查询逻辑。

1. if 标签:条件判断的基石


if 标签是最基础的动态 SQL 工具,它能根据传入的参数动态决定是否包含某个 SQL 片段。比如在用户查询接口中,如果用户传入了姓名参数,就添加姓名过滤条件;否则跳过。

示例

xml
<select id="findUser" resultType="User">
  SELECT * FROM users
  <where>
    <if test="username != null">
      AND username = #{username}
    if>
    <if test="age != null">
      AND age = #{age}
    if>
  where>
select>

这里 where 标签会自动处理第一个 AND,避免生成 WHERE AND 这样的语法错误。

2. choose/when/otherwise:多条件分支选择


当有多个互斥条件时,choose 标签就派上用场了。它类似 Java 中的 switch 语句,只会选择一个符合条件的分支执行。

场景
假设一个商品搜索接口,优先按商品名称搜索,其次按分类搜索,都不满足时返回热门商品。

实现

xml
<select id="searchProducts" resultType="Product">
  SELECT * FROM products
  <where>
    <choose>
      <when test="name != null">
        name LIKE CONCAT('%', #{name}, '%')
      when>
      <when test="categoryId != null">
        category_id = #{categoryId}
      when>
      <otherwise>
        is_hot = 1
      otherwise>
    choose>
  where>
select>

3. foreach:批量操作的利器


批量插入、更新或查询时,foreach 标签能遍历集合或数组,生成对应的 SQL 片段。比如批量删除用户时:

示例

xml
<delete id="deleteUsers">
  DELETE FROM users
  WHERE id IN
  <foreach collection="ids" item="id" open="(" separator="," close=")">
    #{id}
  foreach>
delete>

这里 collection 指定集合参数名,item 是当前遍历的元素,openclose 定义包裹的符号。

4. trim/where/set:SQL 语句的美容师


  • trim:自定义前缀、后缀,移除多余的关键字。
    场景:动态更新用户信息时,只更新有值的字段。

    xml
    <update id="updateUser">
      UPDATE users
      <trim prefix="SET" suffixOverrides=",">
        <if test="username != null">username = #{username},if>
        <if test="email != null">email = #{email},if>
      trim>
      WHERE id = #{id}
    update>
    

    prefix="SET" 会在开头添加 SETsuffixOverrides="," 移除最后一个逗号。

  • where:自动处理 WHERE 子句,移除开头的 ANDOR

  • set:类似 trim,专门用于更新语句,自动添加 SET 并处理逗号。


5. sqlinclude:代码复用的魔法


重复的 SQL 片段可以用 标签定义,再通过 引用。比如多个查询都需要用户基本字段:

定义片段

xml
<sql id="Base_Columns">
  id, username, email, create_time
sql>

引用片段

xml
<select id="getUser" resultType="User">
  SELECT <include refid="Base_Columns"/> FROM users WHERE id = #{id}
select>

? 2025 最新实战案例解析


案例 1:电商平台复杂搜索优化


某电商平台需要根据商品名称、价格区间、品牌等条件动态搜索商品,同时支持分页和排序。

动态 SQL 实现

xml
<select id="searchGoods" resultType="Goods">
  SELECT * FROM goods
  <where>
    <if test="name != null">
      AND name LIKE CONCAT('%', #{name}, '%')
    if>
    <if test="minPrice != null and maxPrice != null">
      AND price BETWEEN #{minPrice} AND #{maxPrice}
    if>
    <if test="brandIds != null">
      AND brand_id IN
      <foreach collection="brandIds" item="id" open="(" separator="," close=")">
        #{id}
      foreach>
    if>
  where>
  <if test="orderBy != null">
    ORDER BY ${orderBy} ${sort}
  if>
  LIMIT #{offset}, #{pageSize}
select>

优化点

  • 使用 CONCAT 避免 SQL 注入,同时保证索引有效。
  • 分页参数 offsetpageSize#{} 预编译,提升性能。
  • 排序字段 orderBy${} 直接拼接,但需在代码层严格校验允许的值,防止注入。

案例 2:批量插入性能优化


在日志系统中,需要批量插入大量日志数据。传统单条插入性能低下,使用 foreach 结合 JDBC 批处理能大幅提升效率。

XML 配置

xml
<insert id="batchInsertLogs">
  INSERT INTO logs (event_type, content, operator)
  VALUES
  <foreach collection="logs" item="log" separator=",">
    (#{log.eventType}, #{log.content}, #{log.operator})
  foreach>
insert>

Java 代码

java
try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
  LogMapper mapper = session.getMapper(LogMapper.class);
  for (Log log : logs) {
    mapper.batchInsertLogs(log);
  }
  session.commit();
}

性能对比

  • 单条插入:耗时约 100ms / 条。
  • 批量插入(1000 条):耗时约 200ms,提升 500 倍!

? 常见问题与解决方案


问题 1:动态 SQL 导致的 SQL 注入风险


原因:使用 ${} 直接拼接参数,未经过预编译。
解决方案

  • 永远用 #{} 代替 ${},Mybatis 会自动转义参数。
  • 对于排序字段等必须动态拼接的场景,在代码层校验允许的字段值。

示例

xml

ORDER BY ${orderBy}


ORDER BY 
<if test="orderBy == 'price' or orderBy == 'create_time'">
  ${orderBy}
if>

问题 2:N+1 查询问题


场景:查询订单时关联查询用户信息,若订单数量大,会导致多次数据库查询。
解决方案

  • 使用 join 替代嵌套查询。
  • 启用 Mybatis 的延迟加载(lazyLoadingEnabled=true),按需加载关联数据。

示例

xml
<resultMap id="OrderWithUserMap" type="Order">
  <association property="user" column="user_id" select="getUser" fetchType="lazy"/>
resultMap>

问题 3:动态 SQL 可读性差


原因:逻辑复杂时,XML 标签嵌套过多,难以维护。
解决方案

  • 将复杂逻辑拆分成多个 sql 片段,通过 include 组合。
  • 使用注释说明每个标签的作用。
  • 优先在 Java 层处理部分逻辑,减少 XML 中的条件判断。

问题 4:批量操作超时


原因:数据量过大时,生成的 SQL 语句过长,导致数据库连接超时。
解决方案

  • 分批处理数据,每次插入 1000 - 5000 条。
  • 调整数据库连接参数(如 socketTimeout)。
  • 使用数据库批量插入语法(如 MySQL 的 LOAD DATA)。

?️ 性能优化技巧


  1. 预编译 SQL
    Mybatis 会对 #{} 参数进行预编译,避免重复解析 SQL,提升执行效率。

  2. 合理使用缓存

    • 一级缓存(默认开启):在同一个 SqlSession 内缓存查询结果。
    • 二级缓存:跨 SqlSession 缓存,适合读多写少的场景。

    xml
    <cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
    

  3. 批量操作优化

    • 启用 JDBC 批处理:在数据库 URL 中添加 rewriteBatchedStatements=true
    • 配置 Mybatis 全局批量执行器:
      xml
      <settings>
        <setting name="defaultExecutorType" value="BATCH"/>
      settings>
      


  4. 避免全表扫描

    • 确保动态条件字段有索引。
    • 避免使用 %${value}% 这样的模糊查询,改用 #{value}% 并创建前缀索引。


? 2025 最新工具与插件推荐


  1. MyBatis-Flex
    一个轻量级的 Mybatis 增强框架,提供更简洁的 API 和性能优化。支持动态 SQL、多表查询、分页等,代码生成器还能自动生成实体类和 Mapper。
    官网:https://mybatis-flex.com/

  2. PageHelper
    分页插件,支持多种数据库,配置简单。2025 年新版本优化了与 Mybatis-Plus 的兼容性。
    使用方式

    java
    PageHelper.startPage(pageNum, pageSize);
    List<User> list = userMapper.selectAll();
    

  3. SQL 染色插件
    京东云开发的插件,通过在 SQL 注释中添加标记(如 statementId),快速定位 SQL 来源,方便排查慢查询。
    GitHub 地址:https://github.com/xxx/sql-dye-plugin


? 总结


Mybatis 的动态 SQL 是提升开发效率和数据库操作灵活性的关键工具。2025 年的最新实践中,结合批量操作优化、缓存策略和新插件,能进一步提升系统性能。记住:

  • 多用 #{} 防注入少用 if 嵌套保可读性
  • 批量操作分批处理复杂逻辑拆分成片段
  • 监控 SQL 执行按需调整优化策略

掌握这些技巧,你就能轻松驾驭动态 SQL,写出高效、优雅的数据库代码。最后提醒一句:技术在进步,记得定期关注 Mybatis 官方文档和社区动态,保持技术敏锐度!

该文章由dudu123.com嘟嘟 ai 导航整理,嘟嘟 AI 导航汇集全网优质网址资源和最新优质 AI 工具

分享到:

相关文章

创作资讯2025-01-23

2025 最新 AI 率免费检测:方法、工具与降 AI 率实用技巧

🚀 2025 最新 AI 率免费检测:方法、工具与降 AI 率实用技巧 AI 生成内容的普及,让检测和降低 AI 率成了刚需。今天就来聊聊怎么用免费工具检测 AI 率,以及超实用的降 AI 率技巧。

第五AI
创作资讯2025-04-11

新手找对标账号,应该找“头部大号”还是“腰部账号”?

🔍 新手找对标账号:头部大号 vs 腰部账号,怎么选更靠谱? 刚开始做自媒体的朋友,心里肯定都有个小目标:找个对标账号跟着学,少走点弯路。但一搜发现,账号分三六九等,头部大号粉丝百万千万,腰部账号粉

第五AI
创作资讯2025-06-25

一个公众号的“信用”是如何被投诉消耗掉的?账号处罚的累积效应

你知道吗?现在做公众号运营,最怕的不是没流量,而是账号 “信用” 一点点被投诉啃掉。很多人觉得偶尔被投诉一次没事,可真等信用分跌到底,功能被限甚至封号时,才发现这根本不是小事。今天就跟你掰开揉碎聊聊,

第五AI
创作资讯2025-02-15

AI一键成文,效率倍增:体验2025最新AI批量原创文章生成器

📝核心功能深度拆解:2025 年 AI 批量生成器的技术突破 2025 年的 AI 批量原创文章生成器,已经从早期的模板填充式工具升级为具备深度语义理解和多模态创作能力的智能系统。以 68 爱写 A

第五AI
推荐2025-08-07

力扣模拟面试防作弊指南:双机位 + 实时代码审查策略揭秘

?双机位布置:打造360°无死角面试环境力扣模拟面试的双机位要求让不少同学犯难,其实把它想象成给电脑装个「监控搭档」就简单了。主机位就是咱们平时用的电脑摄像头,记得调整到能露出整张脸和桌面的角度——下巴别藏在阴影里,键盘也别只露出半个。副机位一般用手机支架固定,放在身体侧后方45度角,这个位置既能拍

第五AI
推荐2025-08-07

Examify AI 是一款怎样的考试平台?2025 最新个性化学习计划解析

?精准提分黑科技!ExamifyAI如何重塑2025考试备考模式?一、核心功能大揭秘:AI如何让考试准备更高效?ExamifyAI作为新一代智能考试平台,最吸引人的地方就是它的自适应学习引擎。这个系统就像一个贴心的私人教练,能根据你的答题数据自动调整学习路径。比如你在数学几何题上错误率高,系统会优先

第五AI
推荐2025-08-07

AI写作如何进行事实核查?确保头条文章信息准确,避免误导读者 - AI创作资讯

上周帮同事核查一篇AI写的行业报告,发现里面把2023年的用户增长率写成了2025年的预测数据。更离谱的是,引用的政策文件号都是错的。现在AI生成内容速度快是快,但这种硬伤要是直接发出去,读者信了才真叫坑人。今天就掰开揉碎了说,AI写作怎么做好事实核查,别让你的头条文章变成 误导重灾区 。​📌AI写

第五AI
推荐2025-08-07

10w+阅读量爆文案例拆解分析:高手都从这5个维度入手 - AI创作资讯

🎯维度一:选题像打靶,靶心必须是「用户情绪储蓄罐」做内容的都清楚,10w+爆文的第一步不是写,是选。选题选不对,后面写得再好都是白搭。高手选选题,就像往用户的「情绪储蓄罐」里投硬币,投对了立刻就能听到回响。怎么判断选题有没有击中情绪?看三个指标:是不是高频讨论的「街头话题」?是不是藏在心里没说的「抽

第五AI
推荐2025-08-07

135编辑器会员值得买吗?它的AI模板库和秀米H5比哪个更丰富? - AI创作资讯

📌135编辑器会员值不值得买?AI模板库和秀米H5谁更胜一筹?🔍135编辑器会员的核心价值解析企业级商用保障与效率提升135编辑器的企业会员堪称新媒体运营的「合规保险箱」。根据实际案例,某团队通过企业会员节省了大量设计费用,完成多篇内容创作,单篇成本从千元降至百元内。这得益于其海量正版模板和素材库,

第五AI
推荐2025-08-07

新公众号被限流怎么办?粉丝增长影响分析及 2025 恢复指南 - AI创作资讯

新公众号被限流怎么办?粉丝增长影响分析及2025恢复指南🔍新公众号限流的核心原因解析新公众号被限流,往往是多个因素叠加的结果。根据2025年最新数据,超过70%的限流案例与内容质量直接相关。比如,有些新手喜欢用“震惊体”标题,像“惊!某公众号三天涨粉十万”,这类标题在2025年的算法里已经被明确标记

第五AI
推荐2025-08-07

AI内容重复率太高怎么办?掌握这些技巧轻松通过AIGC检测 - AI创作资讯

⚠️AI内容重复率高的3大核心原因现在用AI写东西的人越来越多,但很多人都会遇到同一个问题——重复率太高。明明是自己用工具生成的内容,一检测却显示和网上某些文章高度相似,这到底是为什么?最主要的原因是AI训练数据的重叠性。不管是ChatGPT还是国内的大模型,训练数据来源其实大同小异,都是爬取的互联

第五AI
推荐2025-08-07

135编辑器让排版更简单 | 专为公众号运营者设计的效率工具 - AI创作资讯

🌟135编辑器:公众号运营者的效率革命做公众号运营的朋友都知道,排版是个费时费力的活。一篇文章从内容到排版,没几个小时根本搞不定。不过现在好了,135编辑器的出现,彻底改变了这一现状。135编辑器是提子科技旗下的在线图文排版工具,2014年上线至今,已经成为国内新媒体运营的主流工具之一。它的功能非常

第五AI
推荐2025-08-07

朱雀 AI 检测抗绕过方法:2025 最新技术解析与实测对比 - AI创作资讯

🔍朱雀AI检测抗绕过方法:2025最新技术解析与实测对比🔍在AI生成内容泛滥的今天,腾讯朱雀AI检测系统凭借其多模态分析技术和百万级数据训练,成为行业标杆。但道高一尺魔高一丈,对抗者们正通过各种技术手段挑战其检测边界。本文将深入解析2025年最新的抗绕过方法,并结合实测数据对比效果。🛠️技术架构解析

第五AI
推荐2025-08-07

AI内容检测免费工具有哪些?为什么我最终选择了付费的第五AI? - AI创作资讯

🔍CopyLeaks:看似全能的免费选手​CopyLeaks算是免费AI检测工具里名气不小的。它支持Word、PDF这些常见文件格式,甚至连图片里的文字都能提取出来检测。语言方面也挺厉害,中英日韩这些主流语言都能hold住。​但免费版真的不够用,单篇检测最多就500字,稍微长点的文章就得切好几段。而

第五AI