亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

mybatis之foreach用法詳解

 更新時(shí)間:2019年12月25日 11:17:43   作者:Boblim  
這篇文章主要介紹了mybatis之foreach用法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在做mybatis的mapper.xml文件的時(shí)候,我們時(shí)常用到這樣的情況:動(dòng)態(tài)生成sql語句的查詢條件,這個(gè)時(shí)候我們就可以用mybatis的foreach了

foreach元素的屬性主要有item,index,collection,open,separator,close。

  • item:集合中元素迭代時(shí)的別名,該參數(shù)為必選。
  • index:在list和數(shù)組中,index是元素的序號(hào),在map中,index是元素的key,該參數(shù)可選
  • open:foreach代碼的開始符號(hào),一般是(和close=")"合用。常用在in(),values()時(shí)。該參數(shù)可選
  • separator:元素之間的分隔符,例如在in()的時(shí)候,separator=","會(huì)自動(dòng)在元素中間用“,“隔開,避免手動(dòng)輸入逗號(hào)導(dǎo)致sql錯(cuò)誤,如in(1,2,)這樣。該參數(shù)可選。
  • close: foreach代碼的關(guān)閉符號(hào),一般是)和open="("合用。常用在in(),values()時(shí)。該參數(shù)可選。
  • collection: 要做foreach的對(duì)象,作為入?yún)r(shí),List對(duì)象默認(rèn)用"list"代替作為鍵,數(shù)組對(duì)象有"array"代替作為鍵,Map對(duì)象沒有默認(rèn)的鍵。當(dāng)然在作為入?yún)r(shí)可以使用@Param("keyName")來設(shè)置鍵,設(shè)置keyName后,list,array將會(huì)失效。 除了入?yún)⑦@種情況外,還有一種作為參數(shù)對(duì)象的某個(gè)字段的時(shí)候。舉個(gè)例子:如果User有屬性List ids。入?yún)⑹荱ser對(duì)象,那么這個(gè)collection = "ids".如果User有屬性Ids ids;其中Ids是個(gè)對(duì)象,Ids有個(gè)屬性List id;入?yún)⑹荱ser對(duì)象,那么collection = "ids.id"

在使用foreach的時(shí)候最關(guān)鍵的也是最容易出錯(cuò)的就是collection屬性,該屬性是必須指定的,但是在不同情況下,該屬性的值是不一樣的,主要有一下3種情況:

  • 如果傳入的是單參數(shù)且參數(shù)類型是一個(gè)List的時(shí)候,collection屬性值為list .
  • 如果傳入的是單參數(shù)且參數(shù)類型是一個(gè)array數(shù)組的時(shí)候,collection的屬性值為array .
  • 如果傳入的參數(shù)是多個(gè)的時(shí)候,我們就需要把它們封裝成一個(gè)Map了,當(dāng)然單參數(shù)也可以封裝成map,實(shí)際上如果你在傳入?yún)?shù)的時(shí)候,在MyBatis里面也是會(huì)把它封裝成一個(gè)Map的,map的key就是參數(shù)名,所以這個(gè)時(shí)候collection屬性值就是傳入的List或array對(duì)象在自己封裝的map里面的key.

針對(duì)最后一條,我們來看一下官方說法:

注意 你可以將一個(gè) List 實(shí)例或者數(shù)組作為參數(shù)對(duì)象傳給 MyBatis,當(dāng)你這么做的時(shí)候,MyBatis 會(huì)自動(dòng)將它包裝在一個(gè) Map 中并以名稱為鍵。List 實(shí)例將會(huì)以“l(fā)ist”作為鍵,而數(shù)組實(shí)例的鍵將是“array”。

所以,不管是多參數(shù)還是單參數(shù)的list,array類型,都可以封裝為map進(jìn)行傳遞。如果傳遞的是一個(gè)List,則mybatis會(huì)封裝為一個(gè)list為key,list值為object的map,如果是array,則封裝成一個(gè)array為key,array的值為object的map,如果自己封裝呢,則colloection里放的是自己封裝的map里的key值。

源碼分析

由于官方文檔對(duì)這塊的使用,描述的比較簡(jiǎn)短,細(xì)節(jié)上也被忽略掉了(可能是開源項(xiàng)目文檔一貫的問題吧),也使用不少同學(xué)在使用中遇到了問題。特別是foreach這個(gè)函數(shù)中,collection屬性做什么用,有什么注意事項(xiàng)。由于文檔不全,這塊只能通過源代碼剖析的方式來分析一下各個(gè)屬性的相關(guān)要求。

collection屬性的用途是接收輸入的數(shù)組或是List接口實(shí)現(xiàn)。但對(duì)于其名稱的要求,Mybatis在實(shí)現(xiàn)中還是有點(diǎn)不好理解的,所以需要特別注意這一點(diǎn)。

下面開始分析源代碼(筆記使用的是Mybatis 3.0.5版本)

先找到Mybatis執(zhí)行SQL配置解析的入口

MapperMethod.java類中publicObject execute(Object[] args)該方法是執(zhí)行的入口.

針對(duì)in集合查詢,對(duì)應(yīng)用就是selectForList或SelctForMap方法。


但不管調(diào)用哪個(gè)方法,都會(huì)對(duì)原來JDK傳入的參數(shù) Object[]類型,通過 getParam方法轉(zhuǎn)換成一個(gè)Object,那這個(gè)方法是做什么的呢?分析源碼如下:

上圖中標(biāo)紅的兩處,很驚訝的發(fā)現(xiàn),一個(gè)參數(shù)與多個(gè)參數(shù)的處理方式是不同的(后續(xù)很多同學(xué)遇到的問題,就有一大部分出自這個(gè)地方)。如果參數(shù)個(gè)數(shù)大于一個(gè),則會(huì)被封裝成Map, key值如果使用了Mybatis的 Param注解,則會(huì)使用該key值,否則默認(rèn)統(tǒng)一使用數(shù)據(jù)序號(hào),從1開始。這個(gè)問題先記下,繼續(xù)分析代碼,接下來如果是selectForList操作(其它操作就對(duì)應(yīng)用相應(yīng)方法),會(huì)調(diào)用DefaultSqlSession的publicListselectList(String statement, Object parameter, RowBounds rowBounds)方法

又一個(gè)發(fā)現(xiàn),見源代碼如下:

上圖標(biāo)紅部分,對(duì)參數(shù)又做了一次封裝,我們看一下代碼


現(xiàn)在有點(diǎn)清楚了,如果參數(shù)類型是List,則必須在collecion中指定為list, 如果是數(shù)據(jù)組,則必須在collection屬性中指定為 array.

現(xiàn)在就問題就比較清楚了,如果是一個(gè)參數(shù)的話,collection的值取決于你的參數(shù)類型。

如果是多個(gè)值的話,除非使用注解Param指定,否則都是數(shù)字開頭,所以在collection中指定什么值都是無用的。下圖是debug顯示結(jié)果。

使用方法

單參數(shù)List 類型

<select id="countByUserList" resultType="_int" parameterType="list">
select count(*) from users
 <where>
  id in
  <foreach item="item" collection="list" separator="," open="(" close=")" index="">
   #{item.id, jdbcType=NUMERIC}
  </foreach>
 </where>
</select>

測(cè)試代碼:

@Test
 public void shouldHandleComplexNullItem() {
  SqlSession sqlSession = sqlSessionFactory.openSession();
  try {
   Mapper mapper = sqlSession.getMapper(Mapper.class);
   User user1 = new User();
   user1.setId(2);
   user1.setName("User2");
   List<User> users = new ArrayList<User>();
   users.add(user1);
   users.add(null);
   int count = mapper.countByUserList(users);
   Assert.assertEquals(1, count);
  } finally {
   sqlSession.close();
  }
 }

上述collection為array,對(duì)應(yīng)的Mapper代碼:

public List dynamicForeach2Test(int[] ids);

對(duì)應(yīng)的測(cè)試代碼:

@Test
 public void dynamicForeach2Test() {
     SqlSession session = Util.getSqlSessionFactory().openSession();
     BlogMapper blogMapper = session.getMapper(BlogMapper.class);
     int[] ids = new int[] {1,3,6,9};
     List blogs = blogMapper.dynamicForeach2Test(ids);
     for (Blog blog : blogs)
     System.out.println(blog);  
     session.close();
 }

3.自己把參數(shù)封裝成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,是傳入的參數(shù)Map的key,對(duì)應(yīng)的Mapper代碼:

public List dynamicForeach3Test(Map params);

對(duì)應(yīng)測(cè)試代碼:

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

注意注意sql語句SELECT * FROM ny_jobs WHERE id IN () 這個(gè)會(huì)報(bào)錯(cuò),所以最后判斷一下Ids是有元素的

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • spring框架集成flyway項(xiàng)目的詳細(xì)過程

    spring框架集成flyway項(xiàng)目的詳細(xì)過程

    今天通過本文給大家分享spring框架集成flyway項(xiàng)目的詳細(xì)過程,由于大多數(shù)都是springboot集成flyway,很少見到spring框架的項(xiàng)目,今天就抽空給大家介紹下spring框架集成flyway項(xiàng)目的方法,一起看看吧
    2021-07-07
  • Java深入分析了解平衡二叉樹

    Java深入分析了解平衡二叉樹

    平衡二叉樹又被稱為AVL樹(有別于AVL算法),且具有以下性質(zhì):它是一棵空樹或它的左右兩個(gè)子樹的高度差的絕對(duì)值不超過1,并且左右兩個(gè)子樹都是一棵平衡二叉樹。本文將詳解介紹一下平衡二叉樹的原理與實(shí)現(xiàn),需要的可以參考一下
    2022-06-06
  • java安全編碼指南之:聲明和初始化說明

    java安全編碼指南之:聲明和初始化說明

    這篇文章主要介紹了java安全編碼指南之:聲明和初始化說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • SpringBoot開啟虛擬線程的實(shí)現(xiàn)流程

    SpringBoot開啟虛擬線程的實(shí)現(xiàn)流程

    虛擬線程(Virtual?Thread)也稱協(xié)程或纖程,是一種輕量級(jí)的線程實(shí)現(xiàn),與傳統(tǒng)的線程以及操作系統(tǒng)級(jí)別的線程(也稱為平臺(tái)線程)相比,它的創(chuàng)建開銷更小、資源利用率更高,本文給大家介紹了SpringBoot如何開啟虛擬線程,需要的朋友可以參考下
    2024-06-06
  • java實(shí)現(xiàn)的冒泡排序算法示例

    java實(shí)現(xiàn)的冒泡排序算法示例

    這篇文章主要介紹了java實(shí)現(xiàn)的冒泡排序算法,結(jié)合實(shí)例形式分析了冒泡排序算法的具體操作步驟與實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-01-01
  • springmvc+spring+mybatis實(shí)現(xiàn)用戶登錄功能(上)

    springmvc+spring+mybatis實(shí)現(xiàn)用戶登錄功能(上)

    這篇文章主要為大家詳細(xì)介紹了springmvc+spring+mybatis實(shí)現(xiàn)用戶登錄功能,比較基礎(chǔ)的學(xué)習(xí)教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Java壓縮文件為ZIP并加密的詳細(xì)步驟

    Java壓縮文件為ZIP并加密的詳細(xì)步驟

    Zip是一種常用的文件壓縮格式,下面這篇文章主要給大家介紹了關(guān)于Java壓縮文件為ZIP并加密的詳細(xì)步驟,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • Java Filter 過濾器詳細(xì)介紹及實(shí)例代碼

    Java Filter 過濾器詳細(xì)介紹及實(shí)例代碼

    Filter也稱之為過濾器,它是Servlet技術(shù)中最實(shí)用的技術(shù),本文章WEB開發(fā)人員通過Filter技術(shù),對(duì)web服務(wù)器管理的所有web資源進(jìn)行攔截,從而實(shí)現(xiàn)一些特殊的功能,本文章將向大家介紹Java 中的 Filter 過濾器,需要的朋友可以參考一下
    2016-12-12
  • 詳解Http請(qǐng)求中Content-Type講解以及在Spring MVC中的應(yīng)用

    詳解Http請(qǐng)求中Content-Type講解以及在Spring MVC中的應(yīng)用

    這篇文章主要介紹了Http請(qǐng)求中Content-Type講解以及在Spring MVC中的應(yīng)用的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • SpringBoot自定義工具類實(shí)現(xiàn)Excel數(shù)據(jù)存入MySQL數(shù)據(jù)庫

    SpringBoot自定義工具類實(shí)現(xiàn)Excel數(shù)據(jù)存入MySQL數(shù)據(jù)庫

    這篇文章主要為大家詳細(xì)介紹了如何使用EasyExcel讀取Excel內(nèi)數(shù)據(jù)并轉(zhuǎn)換為csv格式數(shù)據(jù),然后實(shí)現(xiàn)字符串分割,分割出屬性名和屬性值建表插入MySQL數(shù)據(jù)庫中,感興趣的可以了解下
    2024-03-03

最新評(píng)論