当前位置: 首页 > news >正文

MyBatis 动态 SQL 完整笔记


MyBatis 动态 SQL 完整笔记


一、核心动态 SQL 标签与用法

1. 条件控制类标签

  • <if>:基础条件判断
    示例:根据 nameage 动态筛选用户

    <if test="name != null and name != ''">AND user_name = #{name}
    </if>
    
  • <choose>/<when>/<otherwise>:多条件分支
    示例:类似 Java 的 switch-case,优先匹配首个满足条件的 <when>

    <choose><when test="type == 'admin'">AND role = 'admin'</when><otherwise>AND role = 'guest'</otherwise>
    </choose>
    

2. 语法修正类标签

  • <where>:自动处理 WHERE 关键字和首条条件前的 AND/OR

    <where><if test="age != null">AND age = #{age}</if>
    </where>
    
  • <trim>:更灵活的语法修正(替代 <where><set>
    示例:自定义前缀/后缀及需删除的字符

    <trim prefix="WHERE" prefixOverrides="AND |OR"><if test="name != null">AND name=#{name}</if>
    </trim>
    
  • <set>:自动处理 UPDATE 语句的 SET 子句
    示例:动态更新字段并去除末尾逗号

    <set><if test="name != null">name=#{name},</if><if test="age != null">age=#{age}</if>
    </set>
    

3. 集合处理类标签

  • <foreach>:遍历集合(批量操作/IN 查询)

    <foreach collection="list" item="item" open="(" separator="," close=")">#{item.id}
    </foreach>
    
  • <bind>:预定义变量(优化模糊查询等场景)

    <bind name="namePattern" value="'%' + name + '%'"/>
    WHERE username LIKE #{namePattern}
    

二、性能优化与最佳实践

1. OGNL 表达式优化

  • 避免复杂嵌套表达式,优先在 Java 层处理判断逻辑
    <if test="@com.utils.MyBatisUtils@isValid(name)">
    

2. 批量操作优化

  • 使用 BATCH 模式执行 SqlSession,减少数据库连接开销
  • 分批次处理超大数据集(如每 1000 条提交一次)

3. 缓存策略

  • 二级缓存配置(Mapper 级别,跨会话共享)
    <mapper namespace="com.UserMapper"><cache eviction="LRU" flushInterval="60000"/>
    </mapper>
    
  • 注意脏读问题:更新操作后手动清除缓存
    <update id="updateUser" flushCache="true">
    

三、高频场景实战示例

1. 动态排序与分页

<select id="selectUsers" resultMap="UserResultMap">SELECT * FROM users<where><if test="orderBy != null">ORDER BY ${orderBy} <!-- 注意 SQL 注入风险 --></if><if test="offset >=0 and limit >0">LIMIT #{offset}, #{limit}</if></where>
</select>

2. 多字段模糊查询

<bind name="searchKey" value="'%' + key + '%'"/>
<where>(title LIKE #{searchKey} OR content LIKE #{searchKey})
</where>

3. 批量插入优化

<insert id="batchInsert">INSERT INTO users (name, age) VALUES<foreach collection="list" item="user" separator=",">(#{user.name}, #{user.age})</foreach>ON DUPLICATE KEY UPDATE age=VALUES(age)
</insert>

四、安全与规范

1. 防 SQL 注入

  • 禁止直接拼接 ${} 参数(除非绝对可信)
  • 使用 #{} 预编译参数化查询

2. 参数校验

  • 集合判空:<if test="list != null and !list.isEmpty()">
  • 字符串处理:<if test="name != null and name.trim() != ''">

3. 类型安全

  • 显式声明 jdbcType(避免 NULL 类型推断错误)
    #{age,jdbcType=INTEGER}
    

五、高级特性

1. 注解动态 SQL

@SelectProvider(type = UserSqlBuilder.class, method = "buildQuery")
List<User> findUsers(UserQuery query);

2. 动态表名映射

<select id="selectByTable" resultType="map">SELECT * FROM ${tableName}
</select>

最佳实践总结

  1. 优先使用 <where>/<set> 替代手动处理 SQL 语法
  2. 复杂条件判断应前移至 Java 代码处理
  3. 批量操作需配合数据库连接池优化
  4. 高频读场景启用二级缓存,但注意数据一致性
  5. 使用 <bind> 统一处理格式转换(如日期/模糊查询)
http://www.xdnf.cn/news/347419.html

相关文章:

  • 深泽多层电路在PCB行业中属于什么水平
  • laravel 使用异步队列,context带的上下文造成反序列化出问题
  • sql server限制用户只能访问特定表
  • PWN基础-ROP技术-ret2syscall-64位程序栈溢出利用
  • el-table合并单元
  • 【基础知识】李雅普诺夫方程与李雅普诺夫函数
  • 985高校查重率“隐性阈值”:低于5%可能被重点审查!
  • 从艾米・阿尔文看 CTO 的多面特质与成长路径
  • 英皇娱乐X乐华娱乐携手造星!“英皇乐华青少年艺人培训班”正式启动!
  • 深度学习-159-综述之混合专家模型和推理模型以及工作流和智能体的概念
  • Elastic:如何构建由 AI 驱动的数字客户体验策略
  • 计算机网络-LDP工作过程详解
  • 代码随想录算法训练营第60期第三十天打卡
  • C++之set和map的运用
  • MySQL 数据库
  • AI人工智能在交通物流领域的应用
  • web 自动化之 Selenium 元素定位和浏览器操作
  • 探索 C++ 在行业应用与技术融合中的核心价值
  • Baklib构建AI就绪知识管理体系
  • 湖北理元理律师事务所的企业债务重组实践:挽救实体经济的法律处方
  • B站pwn教程笔记-8
  • 验证码(笔记)
  • IndoorLink 新一代旗舰电子讲解器,四大革新技术开启破冰之旅
  • Spring AI 入门(持续更新)
  • RDD实现单词计数
  • mybatis-plus-join-boot-starter依赖解决 Join 联表查询
  • Linux复习笔记(二) 网络服务配置(samba /DNS)
  • DeepSeek+Kimi实战:PPT制作教程
  • 多智能体学习CAMEL-调用api
  • 阀门产业发展方向报告(石油化工阀门应用技术交流大会)