Mybatis foreach標簽含義


背景

考慮以下場景:

InfoTable(信息表):

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

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

Name 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();
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM