天天看點

Mybatis foreach标簽含義

背景

考慮以下場景:

InfoTable(資訊表):

Name Gender Age Score
張三 21 90
李四 20 87
王五 22 92
趙六 19 94
孫七 23 88
周八 91

StatusTable(狀态表,指是否有在考試之前複習):

hasReview

現在,我想知道所有複習過的學生的成績,可以利用mysql中的子查詢來實作:

SELECT Score 
FROM InfoTable 
WHERE Name in (SELECT Name 
               FROM StatusTable 
               WHERE hasReview = '是');
           

這種方式非常友善,我們隻要把查詢條件寫出來,剩下的操作都由mysql來處理。而在實際場景中,為了減少底層耦合,我們一般不通過mysql中的子查詢方式聯表查詢,而是先執行子查詢得到結果集,再以結果集作為條件執行外層查詢。通常情況下,子查詢和外層查詢由上層的不同服務執行,這樣就在一定程度上達到了底層資料庫解耦的目的。注意這種實作方式将mysql内部的一部分複雜操作抛給了我們。這時,Mybatis中的

foreach

标簽就有了用武之地。

Mybatis 中

foreach

标簽的用法

還以剛才的例子來說,先執行子查詢

SELECT Name FROM StatusTable WHERE hasReview = '是'
           

再執行外層查詢,就是

SELECT Score 
FROM InfoTable 
WHERE Name in ('張三' , '王五', '趙六', '周八');
           

也就是一個批量查詢操作,将其抽象一下(假設有三個條件):

SELECT * 
FROM <tableName> 
WHERE <ColumnName> IN (<case1>,<case2>,<case3>)
           

實際情況中,case可能遠不止3個,這時可以在XXXMapper.xml檔案中利用Mybatis中的

foreach

編寫sql語句:

SELECT * 
FROM <tableName> 
WHERE <ColumnName> IN 
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
    #{item}
</foreach>
           

就可以實作相同的效果了。

那麼問題來了,

foreach

标簽中各種參數是什麼含義呢?

  • collection
    1. 如果傳入的是單參數且參數類型是一個List的時候,collection屬性值為list
    2. 如果傳入的是單參數且參數類型是一個array數組的時候,collection的屬性值為array
    3. 如果傳入的參數是多個的時候,我們就需要把它們封裝成一個Map了,當然單參數也可以封裝成map,實際上如果你在傳入參數的時候,在breast裡面也是會把它封裝成一個Map的,map的key就是參數名,是以這個時候collection屬性值就是傳入的List或array對象在自己封裝的map裡面的key
  • index 集合疊代位置
  • item 集合中的每一個元素别名
  • open 開始符号,例如這裡的

    (

    ,就對應于

    IN (<case1>,<case2>,<case3>)

    中IN後面的第一個

    (

  • separator 分隔符,例如這裡的

    ,

    IN (<case1>,<case2>,<case3>)

    中的

    ,

  • close 結束符号,例如這裡的

    )

    IN (<case1>,<case2>,<case3>)

    <case3>

    後面的

    )

參考

mybatis foreach标簽的解釋 與常用之處

Mybatis中屬性的含義 之 collection

1.eg:

<select id="getEmpsInNames" resultType="emp">
	select * from emp where ename in
	<foreach collection="list" index="index" item="name" open="("
		separator="," close=")">
		#{name}
	</foreach>
</select>

           
對應的測試代碼:
@Test
public void dynamicForeachTest() {
    SqlSession session = Util.getSqlSessionFactory().openSession();
    BlogMapper blogMapper = session.getMapper(BlogMapper.class);
    List<Integer> ids = new ArrayList<Integer>();
    ids.add(1);
    ids.add(3);
    ids.add(6);
    List<Blog> blogs = blogMapper.dynamicForeachTest(ids);
    for (Blog blog : blogs)
        System.out.println(blog);
    session.close();
}
           
2.eg:
<select id="dynamicForeach2Test" resultType="Blog">
    select * from t_blog where id in
    <foreach collection="array" index="index" item="item" open="(" 
    	separator="," close=")">
        #{item}
    </foreach>
</select>
           
@Test
public void dynamicForeach2Test() {
    SqlSession session = Util.getSqlSessionFactory().openSession();
    BlogMapper blogMapper = session.getMapper(BlogMapper.class);
    int[] ids = new int[] {1,3,6,9};
    List<Blog> blogs = blogMapper.dynamicForeach2Test(ids);
    for (Blog blog : blogs)
        System.out.println(blog);
    session.close();
}
           

3.eg:

​ 自己把參數封裝成Map的類型

<select id="dynamicForeach3Test" resultType="Blog">
    select * from t_blog where title like "%"#{title}"%" and id in
    <foreach collection="ids" index="index" item="item" open="(" 
        separator="," close=")">
        #{item}
    </foreach>
</select>
           

上述collection的值為ids,是傳入的參數Map的key,對應的Mapper代碼:

public List dynamicForeach3Test(Map<String, Object> params);

對應測試代碼:

@Test
public void dynamicForeach3Test() {
    SqlSession session = Util.getSqlSessionFactory().openSession();
    BlogMapper blogMapper = session.getMapper(BlogMapper.class);
    final List<Integer> ids = new ArrayList<Integer>();
    ids.add(1);
    ids.add(2);
    ids.add(3);
    ids.add(6);
    ids.add(7);
    ids.add(9);
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("ids", ids);
    params.put("title", "中國");
    List<Blog> blogs = blogMapper.dynamicForeach3Test(params);
    for (Blog blog : blogs)
        System.out.println(blog);
    session.close();
}
           

『注:本文來自部落格園“小溪的部落格”,若非聲明均為原創内容,請勿用于商業用途,轉載請注明出處http://www.cnblogs.com/xiaoxi666/』