前言:学习自
官方文档:https://mybatis.org/mybatis-3/zh/dynamic-sql.html

文章目录

  • 一、动态SQL
  • 1、if
  • 2、choose (when, otherwise)
  • 3、trim (where, set)
  • where
  • set
  • trim
  • 3.foreach
  • 二、SQL片段

一、动态SQL

1、if

MyBatis知识汇总(第九篇)动态SQL + SQL片段_mybatis


此处,用了不正规的方法,为了避免第一个if匹配失败而导致WHERE后之间出现AND的情况,官网也提供了where标签(见下文trim (where, set)部分)

测试类

@Test
public void testQueryBlogIF() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

//SELECT * FROM blog WHERE 1 = 1
HashMap<String, String> map = new HashMap<>();
List<Blog> blogs = mapper.queryBlogIF(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
System.out.println("------------------------------");

//SELECT * FROM blog WHERE 1 = 1 AND title = #{title}
map = new HashMap<>();
map.put("title", "Mybatis如此简单");
blogs = mapper.queryBlogIF(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
System.out.println("------------------------------");

//SELECT * FROM blog WHERE 1 = 1 AND title = #{title} AND author = #{author}
map = new HashMap<>();
map.put("title", "Java如此简单");
map.put("author", "狂神说");
blogs = mapper.queryBlogIF(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}

MyBatis知识汇总(第九篇)动态SQL + SQL片段_java_02

2、choose (when, otherwise)

(注:也建议将choose嵌套进where标签)

choose只会选中其中一个when,或是otherwise,之后便退出

MyBatis知识汇总(第九篇)动态SQL + SQL片段_sql_03

3、trim (where, set)

where

MyBatis知识汇总(第九篇)动态SQL + SQL片段_sql_04


MyBatis知识汇总(第九篇)动态SQL + SQL片段_mysql_05

set

MyBatis知识汇总(第九篇)动态SQL + SQL片段_数据库_06

trim

(1)trim实现where功能

  • prefix="WHERE"能够动态地在行首插入 WHERE关键字
  • prefixOverrides是指每个where标签中的每个子部分(如if,或when或otherwise部分)的前缀部分,即AND或OR,若AND或OR为子句部分的第一句,则删除它们

MyBatis知识汇总(第九篇)动态SQL + SQL片段_java_07

(2)trim实现set功能

  • prefix="SET"能够动态地在行首插入 SET 关键字

  • suffixOverrides是指set标签中的每个子部分(如if部分)的后缀部分,即逗号",",若某子句为SQL语句最后一部分,即逗号在SQL语句最后,则会删掉额外的逗号
  • MyBatis知识汇总(第九篇)动态SQL + SQL片段_java_08

3.foreach

MyBatis知识汇总(第九篇)动态SQL + SQL片段_数据库_09


【例子】:根据一部分id查询出对应行

Mapper.xml

<select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from blog
<where>
<!--
collection:指定输入对象中的集合属性
item:每次遍历生成的对象
open:开始遍历时的拼接字符串
close:结束时拼接的字符串
separator:遍历对象之间需要拼接的字符串
select * from blog where 1=1 and (id=1 or id=2 or id=3)
-->
<foreach collectinotallow="ids" item="id" open="AND (" close=")" separator="OR">
id = #{id}
</foreach>
</where>
</select>

测试类

@Test
public void testQueryBlogForeach() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

ArrayList<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
HashMap map = new HashMap();
map.put("ids", ids);
List<Blog> blogs = mapper.queryBlogForeach(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}

MyBatis知识汇总(第九篇)动态SQL + SQL片段_java_10

二、SQL片段

实现标签片段的复用

  • 使用sql标签抽取可复用的部分
  • 在需要使用的地方使用include标签

<sql id="if-title-author">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
AND author = #{author}
</if>
</sql>

<select id="queryBlogIF" parameterType="map" resultType="blog">
SELECT * FROM blog
<where>
<include refid="if-title-author"></include>
</where>
</select>

注意事项:

  • 最好基于单表来定义SQL片段
  • 不要抽取出where标签