Mybatis foreach標籤含義

背景

考慮如下場景:java

InfoTable(信息表):mysql

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

StatusTable(狀態表,指是否有在考試以前複習):sql

Name hasReview
張三
李四
王五
趙六
孫七
周八

如今,我想知道全部複習過的學生的成績,能夠利用mysql中的子查詢來實現:數據庫

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

這種方式很是方便,咱們只要把查詢條件寫出來,剩下的操做都由mysql來處理。而在實際場景中,爲了減小底層耦合,咱們通常不經過mysql中的子查詢方式聯表查詢,而是先執行子查詢獲得結果集,再以結果集做爲條件執行外層查詢。一般狀況下,子查詢和外層查詢由上層的不一樣服務執行,這樣就在必定程度上達到了底層數據庫解耦的目的。注意這種實現方式將mysql內部的一部分複雜操做拋給了咱們。這時,Mybatis中的foreach標籤就有了用武之地。數組

Mybatis 中foreach標籤的用法

還以剛纔的例子來講,先執行子查詢session

SELECT Name FROM StatusTable WHERE hasReview = '是'

再執行外層查詢,就是mybatis

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

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

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>

就能夠實現相同的效果了。.net

那麼問題來了,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();
}
相關文章
相關標籤/搜索