---
# System prepended metadata

title: 動態SQL的Foreach
tags: [Mybatis-動態SQL]

---

# 動態SQL的Foreach
###### tags: `Mybatis-動態SQL`

## SQL片段
有的時候，我們可能會將一些功能抽取出來，方便復用

1.使用sql標籤抽取公共的部分
```xml=
    <sql id="if-title-author">
        <if test="title != null">
            title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
    </sql>
```
2.在需要使用的地方使用include標籤引用即可
```xml=
    <select id="queryBlogIF" parameterType="map" resultType="blog">
        <!--where 1 = 1 必定為真-->
        select * from mybatis.blog
        <where>
            <include refid="if-title-author"/>
        </where>
    </select>
```
**注意事項**
* 最好基於單表來定義SQL片段(避免過於複雜，降低復用率)
* 不要存在where標籤

## Foreach
```sql=
select * from user where 1=1 and 

    <foreach item="id" index="index" collection="ids"
        open="ID in (" separator="or" close=")" nullable="true">
          #{id}
    </foreach>
    
(id = 1 or id = 2 id = 3)
```

1.foreach使用
```xml=
<!--我們現在傳遞一個萬能的map，這map中可以存在一個集合    -->
    <select id="queryBlogForeach" parameterType="map" resultType="Blog">
        select * from mybatis.blog
        <where>
            <foreach collection="ids" item="id" open="and (" close=")" separator="or">
                id=#{id}
            </foreach>
        </where>
    </select>
```

2.使用
```java=
 @Test
    public void queryBlogForeach(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap map = new HashMap<>();

        ArrayList<Integer> ids = new ArrayList<>();
        ids.add(1);
        ids.add(2);

        map.put("ids",ids);

        List<Blog> blogs = mapper.queryBlogForeach(map);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }
        sqlSession.close();
    }
```
3.輸出(id=1)
![](https://i.imgur.com/Dkf3bPh.png)
(id=1、id=2)
![](https://i.imgur.com/S798rtj.png)


**動態SQL就是在拼接SQL語句，只要保證SQL的正確性，按照SQL的格式去排列組合就可以了**

**建議**
* 先在Mysql中寫出完整的SQL，再對應去修改成為我們的動態SQL實現通用即可