前面我們學(xué)習(xí)了如何使用 Mybatis if、where、trim 等動(dòng)態(tài)語(yǔ)句來處理一些簡(jiǎn)單的查詢操作。對(duì)于一些 SQL 語(yǔ)句中含有 in 條件,需要迭代條件集合來生成的情況,可以使用 foreach 來實(shí)現(xiàn) SQL 條件的迭代。
Mybatis foreach 標(biāo)簽用于循環(huán)語(yǔ)句,它很好的支持了數(shù)據(jù)和 List、set 接口的集合,并對(duì)此提供遍歷的功能。語(yǔ)法格式如下。
<foreach item="item" index="index" collection="list|array|map key" open="(" separator="," close=")"> 參數(shù)值 </foreach>
foreach 標(biāo)簽主要有以下屬性,說明如下。
item:表示集合中每一個(gè)元素進(jìn)行迭代時(shí)的別名。
index:指定一個(gè)名字,表示在迭代過程中每次迭代到的位置。
open:表示該語(yǔ)句以什么開始(既然是 in 條件語(yǔ)句,所以必然以(開始)。
separator:表示在每次進(jìn)行迭代之間以什么符號(hào)作為分隔符(既然是 in 條件語(yǔ)句,所以必然以,作為分隔符)。
close:表示該語(yǔ)句以什么結(jié)束(既然是 in 條件語(yǔ)句,所以必然以)開始)。
使用 foreach 標(biāo)簽時(shí),最關(guān)鍵、最容易出錯(cuò)的是 collection 屬性,該屬性是必選的,但在不同情況下該屬性的值是不一樣的,主要有以下 3 種情況:
如果傳入的是單參數(shù)且參數(shù)類型是一個(gè) List,collection 屬性值為 list。
如果傳入的是單參數(shù)且參數(shù)類型是一個(gè) array 數(shù)組,collection 的屬性值為 array。
如果傳入的參數(shù)是多個(gè),需要把它們封裝成一個(gè) Map,當(dāng)然單參數(shù)也可以封裝成 Map。Map 的 key 是參數(shù)名,collection 屬性值是傳入的 List 或 array 對(duì)象在自己封裝的 Map 中的 key。
本節(jié)示例基于《第一個(gè)MyBatis程序》一節(jié)的代碼實(shí)現(xiàn)。
現(xiàn)有 website 表包含以下記錄。
+----+----------------+----------------------------+-----+---------+---------------------+ | id | name | url | age | country | createtime | +----+----------------+----------------------------+-----+---------+---------------------+ | 1 | 編程幫 | http://www.soo66.com/ | 10 | CN | 2021-02-23 10:20:40 | | 2 | C語(yǔ)言中文網(wǎng) | https://c.cainiaoplus.com/ | 12 | CN | 2021-03-08 11:23:27 | | 3 | 百度 | https://www.baidu.com/ | 18 | CN | 2021-03-08 11:23:53 | | 4 | 淘寶 | https://www.taobao.com/ | 17 | CN | 2021-03-10 10:33:54 | | 5 | Google | https://www.google.com/ | 23 | US | 2021-03-10 10:34:34 | | 6 | GitHub | https://github.com/ | 13 | US | 2021-03-10 10:34:34 | | 7 | Stack Overflow | https://stackoverflow.com/ | 16 | US | 2021-03-10 10:34:34 | | 8 | Yandex | https://www.yandex.ru/ | 11 | RU | 2021-03-10 10:34:34 | +----+----------------+----------------------------+-----+---------+---------------------+
WebsiteMapper.xml 中代碼如下。
<select id="selectWebsite" parameterType="net.biancheng.po.Website" resultType="net.biancheng.po.Website"> SELECT id,name,url,age,country FROM website WHERE age in <foreach item="age" index="index" collection="list" open="(" separator="," close=")"> #{age} </foreach> </select>
WebsiteMapper 類中相應(yīng)方法如下。
public List<Website> selectWebsite(List<Integer> ageList);
測(cè)試代碼如下。
public class Test { public static void main(String[] args) throws IOException { // 讀取配置文件mybatis-config.xml InputStream config = Resources.getResourceAsStream("mybatis-config.xml"); // 根據(jù)配置文件構(gòu)建 SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config); // 通過SqlSessionFactory創(chuàng)建SqlSession SqlSession ss = ssf.openSession(); List<Integer> ageList = new ArrayList<Integer>(); ageList.add(10); ageList.add(12); List<Website> siteList = ss.selectList("net.biancheng.mapper.WebsiteMapper.selectWebsite", ageList); for (Website ws : siteList) { System.out.println(ws); } } }
輸出結(jié)果如下。
DEBUG [main] - ==> Preparing: SELECT id,name,url,age,country FROM website WHERE age in ( ? , ? ) DEBUG [main] - ==> Parameters: 10(Integer), 12(Integer) DEBUG [main] - <== Total: 2 Website[id=1,name=編程幫,url=http://www.soo66.com/,age=10,country=CN] Website[id=2,name=C語(yǔ)言中文網(wǎng),url=https://c.cainiaoplus.com/,age=12,country=CN]