> For the complete documentation index, see [llms.txt](https://bohans.gitbook.io/ji-chu/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bohans.gitbook.io/ji-chu/mybatis/ji-chu-zhi-shi/4.-dong-tai-sql/4.3-wheresettrim-biao-qian-yong-fa.md).

# 4.3 where、set、trim 标签用法

## **where 标签**

```xml
<where>
    ...if标签或choose标签...
</where>
```

where 标签的作用：

* <mark style="color:blue;">**如果该标签包含的元素中有返回值，就插入一个where**</mark>；
* 如果where后面的字符串是<mark style="color:blue;">**以AND和OR开头**</mark>的，就将它们<mark style="color:blue;">剔除</mark>。

<details>

<summary><strong>使用案例</strong></summary>

```xml
<select id="findActiveBlogLike" resultType="Blog">
  SELECT 
  	* 
  FROM BLOG
  WHERE
  <if test="state != null">
    state = #{state}
  </if>
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>
```

* 如果没有匹配的条件会怎么样？最终这条 SQL 会变成这样：

  ```sql
  SELECT * FROM BLOG
  WHERE
  ```
* 如果匹配的只是第二个条件又会怎样？这条 SQL 会是这样:

  ```sql
  SELECT * FROM BLOG
  WHERE
  AND title like 'someTitle'
  ```

**添加where标签后可以轻易地解决上述问题：**

```xml
<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>
```

*<mark style="color:blue;">**where**</mark>*<mark style="color:blue;">**&#x20;**</mark><mark style="color:blue;">**元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。**</mark>

<mark style="color:blue;">**而且，若子句的开头为 “AND” 或 “OR”，**</mark>*<mark style="color:blue;">**where**</mark>*<mark style="color:blue;">**&#x20;**</mark><mark style="color:blue;">**元素也会将它们去除。**</mark>

</details>

## **set 标签**

set 标签的作用：

* <mark style="color:blue;">**如果该标签包含的元素中有返回值，就插入一个set；**</mark>
* 如果set后面的字符串是<mark style="color:blue;">**以逗号结尾的，就将这个逗号剔除**</mark>。

set 标签主要用在**update**语句中，作用和where标签类似，可以参考where标签的使用案例。

## **trim 标签**

where 和 set 标签的功能都可以用trim 标签来实现，并且在底层就是通过TrimSqlNode实现的。

<mark style="color:blue;">**trim**</mark>标签有如下属性:

* **prefix**：当trim元素内包含内容时，会给内容增加prefix指定的前缀。
* **prefixOverrides**：当trim元素内包含内容时，会把内容中匹配的前缀字符串去掉。
* **suffix**：当trim元素内包含内容时，会给内容增加suffix指定的后缀。
* **suffixOverrides**：当trim元素内包含内容时，会把内容中匹配的后缀字符串去掉。

> where 标签对应的trim 的实现如下：
>
> ```xml
> <trim prefix="WHERE" prefixOverrides="AND |OR ">
> </trim>
> ```
>
> 为了避免匹配到andes、orders等单词，这里的AND和OR后面的空格不能省略。**实际**的prefixeOverrides包含“AND”、“OR”、“AND\n”、“OR\n”、“AND\r”、“OR\r”、“AND\t”、“OR\t”，不仅仅是上面提到的两个带空格的前缀。
>
> set 标签对应的trim 实现如下：
>
> ```xml
> <trim prefix="SET" suffixOverrides=",">
> </trim>
> ```
