MyBatis分页查询与动态SQL学习笔记
一、分页查询的两种方式
1. 物理分页(推荐)
特点:
- 在SQL层面实现分页
- 性能更好(大数据量场景)
- 常用实现方式:
PageHelper
插件、手写分页SQL
2. 逻辑分页
特点:
- 查询全部数据后在内存中分页
- 性能较差(小数据量可用)
- 实现方式:
RowBounds
二、实现案例
案例1:使用PageHelper插件(含动态SQL)
|
|
Java调用:
|
|
案例2:手写SQL分页(MySQL)与动态SQL结合
|
|
三、动态SQL核心知识点
1. 常用标签
标签 | 作用 |
---|---|
<if> |
条件判断 |
<choose> |
类似Java的switch-case |
<where> |
自动处理WHERE关键字和AND/OR前缀 |
<set> |
自动处理UPDATE语句的SET部分 |
<foreach> |
遍历集合,常用于IN条件 |
<trim> |
自定义字符串修剪(可替代where/set) |
<bind> |
创建变量并绑定到上下文 |
2. 典型应用场景
场景1:多条件查询
|
|
场景2:动态UPDATE
|
|
场景3:批量插入
|
|
四、面试常见问题与回答建议
Q1:MyBatis动态SQL的实现原理?
回答要点:
- 基于OGNL表达式解析
- 通过XML标签生成最终SQL
- 使用SqlNode和SqlSource构建动态SQL
示例回答:
“MyBatis动态SQL通过解析XML中的特殊标签(如if/where等),根据参数值动态拼接SQL语句。底层使用OGNL表达式求值,最终生成StaticSqlSource或DynamicSqlSource对象。比如
标签会智能处理AND/OR前缀,避免语法错误。”
Q2:如何优化动态SQL的性能?
回答建议:
- 避免过度复杂的动态条件
- 使用
替代手动WHERE 1=1 - 注意
的批量操作数量控制
示例回答:
“我们项目中对动态SQL的优化主要有:1) 对高频查询使用
预处理模糊查询参数;2) 批量操作时控制 的集合大小(分批次处理);3) 复杂查询拆分为多个简单SQL,通过Java代码组合结果。”
Q3:动态SQL和分页结合使用的注意事项?
回答要点:
- 确保分页在最终SQL上执行
- PageHelper要放在动态SQL查询前
- 注意排序字段的索引优化
示例回答:
“结合使用时需注意:1) PageHelper.startPage()必须在动态SQL查询前调用,确保分页是对最终结果集生效;2) 动态WHERE条件中的字段建议建立复合索引;3) 排序字段如果是动态的,需要防范SQL注入。”
五、最佳实践总结
-
分页选择:
- 常规场景用PageHelper
- 超大数据量考虑游标分页(基于索引)
-
动态SQL规范:
1 2 3 4 5 6 7 8 9 10 11 12
<!-- 推荐写法 --> <where> <if test="param != null"> AND column = #{param} </if> </where> <!-- 不推荐写法 --> WHERE 1=1 <if test="param != null"> AND column = #{param} </if>
-
性能监控:
- 开启MyBatis日志检查最终执行的SQL
- 对复杂动态SQL进行压测
💡 面试加分点:可以举例说明如何解决实际项目中遇到的动态SQL问题,例如:“我们曾遇到一个多条件导出功能,通过动态SQL减少70%的冗余代码,同时用PageHelper的count查询优化解决了分页总数性能问题。”
|
|