什么是动态SQL
- 动态 SQL 是指同一个 SQL id 根据不同的条件动态生成不同的 SQL,以满足不同的查询需求。
- 灵活使用动态 SQL 可以提升代码的复用性,提升开发效率。
查询需求1:根据性别查询已激活账号
查询需求2:根据年龄查询已激活账号
查询需求3:根据年龄和性别查询已激活账号
这 3 个 SQL 存在共性,MyBatis 能否可能用 1 个 SQL 实现,从而减少需要维护的 SQL 个数?
if 标签
- if 标签用于进行条件判断,功能类似 Java 的 if。test 属性中的表达式值为 true 时,才会将 if 标签中的 SQL 包含在生成的 SQL 语句中,否则会忽略。
choose、when、otherwise 标签
- 有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 标签,它有点像 Java 中的 switch 语句(官网说像 switch,我认为更像 if、else if、else)。
- 查询需求:年龄非空,根据年龄查;年龄为空,性别非空,根据性别查;年龄、性别都为空,查询所有余额大于1000的账号。
- choose 内只有一个 when 和 otherwise,功能类似 Java 的 if else。
- choose 内只有一个 when,没有 otherwise,功能与 if 标签相同,可以用 if 标签替代。
where 标签
- 查询需求:不希望 status 作为默认条件,如果 status 为空,则不对 status 进行约束
- 上述 SQL,如果 status 为空,会出现什么问题?
- 执行报错,SQL语法错误,where 后直接跟着 and user_age = ?
解决方案一:在 where 后增加 1 = 1
- 实际执行的 SQL 变为
select * from account where 1 = 1 and user_age = ?没有 SQL 无法错误
解决方案二:使用 where 标签
- where 标签只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。
- 若子句的开头为 “AND” 或 “OR”,where 标签也会将它们去除
foreach 标签
- foreach 标签用于对集合进行遍历(尤其是在构建 IN 条件语句的时候)
- 查询需求:查询 id 等于某个列表中某个值的数据记录,如果列表为空,不返回数据记录
- 如果迭代的是 list,index 表示当前迭代的序号,item 表示本次迭代获取到的元素。
- 如果迭代的是 map 或者 Map.Entry 对象的集合时,index 是键,item 是值。
上述代码可以实现需求,但其能否处理 list 为空的情况?
- 处理 list 为空的情况
- 这个 SQL list 为空时不会报错,但返回了表中所有记录,不满足需求。
最终版 SQL
trim 标签
- trim 在英文中是修剪、修饰的意思。trim 标签对 SQL 代码块的头尾进行修改。
- 使用 trim 可以给 SQL 代码块增加、删除前缀,增加、删除后缀。
如果 trim 标签内部为空,则不会增加前缀也不会增加后缀。
trim 标签使用实例
- 使用 trim 标签实现 where 标签:给 sql 语句拼接前缀 where,删除 sql 开头的 and 或者 or
- 使用 trim 标签实现 insertSelective:给 sql 语句前后拼接 ( 和 ),删除 sql 结尾的 ,
trim 标签非常灵活,实际使用时按需求自定义实现功能。
sql、include 标签
- 在实际开发中会遇到许多相同的SQL,比如根据某个条件筛选,这个筛选很多地方都能用到,我们可以将其抽取出来成为一个公用的部分。
- sql 标签用于定义 SQL 片段。其他 SQL 语句可以引用定义好的 SQL 片段,从而实现 SQL 语句的复用,类似 Java 中方法封装的思想。
- include 标签用于引用 SQL 片段。
sql 和 include 标签结合使用,减少了重复代码,提升了代码的可维护性和可读性。