最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于MyBatis的foreach標(biāo)簽常用方法

 更新時(shí)間:2023年05月19日 09:09:43   作者:長(zhǎng)安明月  
這篇文章主要介紹了關(guān)于MyBatis的foreach標(biāo)簽常用方法,foreach 標(biāo)簽可以用來(lái)遍歷數(shù)組、列表和 Map 等集合參數(shù),實(shí)現(xiàn)批量操作或一些簡(jiǎn)單 SQL 操作,需要的朋友可以參考下

一、前言

在 MyBatis 中,常常會(huì)遇到集合類型的參數(shù),雖然我們可以通過(guò) OGNL 表達(dá)式來(lái)訪問(wèn)集合的某一個(gè)元素,但是 OGNL 表達(dá)式無(wú)法遍歷集合。foreach 標(biāo)簽就是專門用來(lái)解決這類問(wèn)題的,foreach 標(biāo)簽可以用來(lái)遍歷數(shù)組、列表和 Map 等集合參數(shù),實(shí)現(xiàn)批量操作或一些簡(jiǎn)單 SQL 操作。

二、foreach 元素屬性簡(jiǎn)介

foreach 元素的屬性主要有 item,index,open,separator,close,collection。各屬性含義如下所示。

2.1 item

集合中元素迭代時(shí)的別名,該參數(shù)為必選。

2.2 index

在 list 和數(shù)組中,index 是元素的序號(hào);在 map 中,index 是元素的 key。該參數(shù)可選。

2.3 open

foreach 代碼的開始符號(hào),一般是 ”(“,和 close=“)” 合用。常用在 in(),values() 時(shí)。該參數(shù)可選。

2.4 separator

元素之間的分隔符,例如在 in() 的時(shí)候,separator=“,” 會(huì)自動(dòng)在元素中間用 “,“ 隔開,避免手動(dòng)輸入逗號(hào)導(dǎo)致 SQL 錯(cuò)誤,如 in(1, 2,) 這樣。該參數(shù)可選。

2.5 close

foreach 代碼的關(guān)閉符號(hào),一般是 ”)“,和 open=“(” 合用。常用在 in(),values()時(shí)。該參數(shù)可選。

2.6 collection

要被 foreach 標(biāo)簽循環(huán)解析的對(duì)象。

foreach 標(biāo)簽的 collection 屬性在接受參數(shù)名時(shí),有兩種情況:

  • 匿名參數(shù)
    當(dāng)在 java 方法中沒有通過(guò) @Param 注解指定參數(shù)名時(shí),列表類型默認(rèn)參數(shù)名為 ”list“,數(shù)組類型默認(rèn)參數(shù)名為 ”array“,Map 對(duì)象沒有默認(rèn)值。
  • 具名參數(shù)
    java 方法中使用了 @Param 注解指定了參數(shù)名稱,則 foreach 中的 collection 屬性必須為參數(shù)名。

在作為入?yún)r(shí)可以使用 @Param(“keyName”) 來(lái)設(shè)置該鍵值,設(shè)置 keyName 后,list、array 將會(huì)失效。除了入?yún)⑦@種情況外,還有一種是作為參數(shù)對(duì)象的某個(gè)字段,例子如下。如果 User 有屬性 List ids。入?yún)⑹?User 對(duì)象,那么這個(gè)collection = “ids”。如果 User 有屬性 Ids ids,其中 Ids 是個(gè)對(duì)象,Ids 有個(gè)屬性 List id,入?yún)⑹?User 對(duì)象,那么 collection = “ids.id”。

注意點(diǎn):在使用 foreach 的時(shí)候,最關(guān)鍵的就是 collection 屬性,該屬性是必須指定的,但是在不同情況下,該屬性的值是不一樣的,主要有以下 3 種情況(未通過(guò) @Param 指定別名時(shí))。

  • 如果傳入的是單參數(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。

三、#{} 與 ${} 的區(qū)別

在使用參數(shù)的過(guò)程中,會(huì)遇到 #{} 與 ${} 的問(wèn)題,因此簡(jiǎn)單總結(jié)下兩者之間的區(qū)別。

  1. ${param} 傳遞的參數(shù)會(huì)被當(dāng)成 SQL 語(yǔ)句中的一部分,比如傳遞表名,字段名,字段類型等數(shù)據(jù)。 例如,傳入值為 id,order by ${param} 則解析成 SQL:order by id。
  2. #{parm} 傳入的數(shù)據(jù)都當(dāng)成一個(gè)字符串,會(huì)對(duì)自動(dòng)傳入的數(shù)據(jù)加一個(gè)雙引號(hào)。 例如,傳入值為 id,select * from table where name = #{param} 則解析成 SQL:select * from table where name = ? (其中問(wèn)號(hào)在執(zhí)行時(shí)傳入值 “id”)。

為了安全,能用 # 的地方就用 # 方式傳參,這樣可以有效的防止 SQL 注入攻擊。

官方說(shuō)明:mybatis 在處理 #{} 時(shí),會(huì)將 SQL 中的 #{} 替換為 “?”,調(diào)用 PreparedStatement 的 set 方法來(lái)賦值;mybatis 在處理 ${} 時(shí),就是把 ${} 替換成變量的值。使用 #{} 可以有效的防止 SQL 注入,提高系統(tǒng)安全性。

四、實(shí)例實(shí)戰(zhàn)

本文以如下幾個(gè)例子簡(jiǎn)單總結(jié)下 foreach 是如何遍歷列表、數(shù)組和 Map 的。

4.1 遍歷 List<String> 列表

Java 層接口

List<Rule> selectRulesByList(List<String> ids);

XML

  <select id="selectRulesByList" resultMap="BaseResultMap">
    SELECT
    <include refid="Base_Column_List" />
    FROM tbl_test_rule WHERE rule_id IN
    <foreach collection="list" open="(" close=")" separator="," item="item" index="index">
      #{item}
    </foreach>
  </select>

運(yùn)行時(shí) SQL 語(yǔ)句

==>  Preparing: SELECT rule_id, rule_name, rule_type FROM tbl_test_rule WHERE rule_id IN ( ? , ? )
==> Parameters: 10001(String), 20002(String)
<==      Total: 2

4.2 遍歷 List<Object> 列表

項(xiàng)目中定義了一個(gè)實(shí)體類 Rule,在批量插入時(shí)需要遍歷 List<Rule>,實(shí)現(xiàn)方式見下文。

Java 層接口

int insertRules(@Param("rules") List<Rule> rules);

XML

  <insert id="insertRules">
    INSERT INTO tbl_test_rule (rule_id, rule_name, rule_type) VALUES
    <foreach collection="rules" separator="," item="rule">
      (#{rule.ruleId}, #{rule.ruleName}, #{rule.ruleType})
    </foreach>
  </insert>

運(yùn)行時(shí) SQL 語(yǔ)句

==>  Preparing: INSERT INTO tbl_test_rule (rule_id, rule_name, rule_type) VALUES (?, ?, ?) , (?, ?, ?)
==> Parameters: ruleId1(String), ruleName1(String), 1(String), ruleId2(String), ruleName2(String), 2(String)
<==    Updates: 2

4.3 遍歷數(shù)組

Java 層接口

List<Rule> selectRulesByArray(String[] ids);

如果 ids 參數(shù)使用 @Param 注解指定了參數(shù)名稱,則 foreach 標(biāo)簽中的 collection 屬性必須為該名稱;但若未指定名稱,則在 foreach 標(biāo)簽中使用默認(rèn)數(shù)組名稱 array,如下所示

XML

  <select id="selectRulesByArray" resultMap="BaseResultMap">
    SELECT
    <include refid="Base_Column_List" />
    FROM tbl_test_rule WHERE rule_id IN
    <foreach collection="array" open="(" close=")" separator="," item="item" index="index">
      #{item}
    </foreach>
  </select>

運(yùn)行時(shí) SQL 語(yǔ)句

==>  Preparing: SELECT rule_id, rule_name, rule_type FROM tbl_test_rule WHERE rule_id IN ( ? , ? )
==> Parameters: 10001(String), 20002(String)
<==      Total: 2

4.4 遍歷 Map 實(shí)現(xiàn) insert into … on duplicate key update

數(shù)據(jù)庫(kù)表 tbl_test_discount,聯(lián)合主鍵(cert_no, rule_id, cycle_id),存儲(chǔ)了不同用戶不同周期下的折扣金額。請(qǐng)求參數(shù) Map 中存儲(chǔ)了某一用戶不同規(guī)則(key 為不同的 rule_id 值)和各個(gè)規(guī)則下的折扣值(value 為 dis_sum),如下方 Java 接口定義。需要實(shí)現(xiàn):當(dāng)數(shù)據(jù)庫(kù)中無(wú)主鍵記錄時(shí),將記錄插入數(shù)據(jù)庫(kù);如數(shù)據(jù)庫(kù)中存在主鍵記錄時(shí),更新折扣值,將折扣值累加計(jì)算(即實(shí)現(xiàn) insert into … on duplicate key update 操作)。過(guò)程示例如下。

Java 層接口

    int saveOrUpd(@Param(value = "certNo") String certNo,
                  @Param(value = "cycleId") String cycleId,
                  @Param(value = "params") Map map);

使用 foreach 標(biāo)簽遍歷 Map 時(shí),collection 屬性值為 @param 注解指定的參數(shù)名,即 params,且 item 是 Map 的鍵值,index 是鍵名。

XML

  <update id="saveOrUpd" parameterType="java.util.Map">
    <foreach collection="params" index="key" item="value">
      insert into tbl_test_discount (cert_no, rule_id, cycle_id, dis_sum) values
      (#{certNo}, #{key}, #{cycleId}, #{value}) on duplicate key update dis_sum = dis_sum + #{value};
    </foreach>
  </update>

mybatis 設(shè)置允許批量更新

mybatis 會(huì)根據(jù)上述 XML 文件的配置,動(dòng)態(tài)生成多條 SQL。要讓 mybatis 成功執(zhí)行多條語(yǔ)句,須開啟允許批量查詢?cè)O(shè)置,即在 jdbc-url 連接信息中添加 &allowMultiQueries=true,如下所示。

spring.datasource.jdbc-url=jdbc:mysql://localhost:3306/testdb?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true

MySQL 連接數(shù)據(jù)庫(kù)時(shí),添加語(yǔ)句 &allowMultiQueries=true 的作用:可以在 SQL 語(yǔ)句后攜帶分號(hào),實(shí)現(xiàn)多語(yǔ)句執(zhí)行;可以執(zhí)行批處理,同時(shí)發(fā)出多個(gè) SQL 語(yǔ)句。

運(yùn)行時(shí) SQL 語(yǔ)句

==>  Preparing: insert into tbl_test_discount (cert_no, rule_id, cycle_id, dis_sum) values (?, ?, ?, ?) on duplicate key update dis_sum = dis_sum + ?; insert into tbl_test_discount (cert_no, rule_id, cycle_id, dis_sum) values (?, ?, ?, ?) on duplicate key update dis_sum = dis_sum + ?; insert into tbl_test_discount (cert_no, rule_id, cycle_id, dis_sum) values (?, ?, ?, ?) on duplicate key update dis_sum = dis_sum + ?; insert into tbl_test_discount (cert_no, rule_id, cycle_id, dis_sum) values (?, ?, ?, ?) on duplicate key update dis_sum = dis_sum + ?;
==> Parameters: testCertNo1(String), 30001(String), 202212(String), 225(Integer), 225(Integer), testCertNo2(String), 20002(String), 202212(String), 385(Integer), 385(Integer), testCertNo3(String), 20001(String), 202212(String), 553(Integer), 553(Integer), testCertNo4(String), 10001(String), 202212(String), 300(Integer), 300(Integer)
<==    Updates: 1

foreach 標(biāo)簽是使用非常廣泛的一個(gè)標(biāo)簽,當(dāng)使用 SQL 進(jìn)行批量插入、查詢時(shí)都可能使用到它。列表遍歷的使用最為廣泛,數(shù)組和 Map 則相對(duì)較少。

到此這篇關(guān)于關(guān)于MyBatis的foreach標(biāo)簽常用方法的文章就介紹到這了,更多相關(guān)MyBatis的foreach標(biāo)簽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java如何把逗號(hào)分隔的String字符串轉(zhuǎn)int集合

    java如何把逗號(hào)分隔的String字符串轉(zhuǎn)int集合

    這篇文章主要介紹了java實(shí)現(xiàn)把逗號(hào)分隔的String字符串轉(zhuǎn)int集合,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 如何將JSP/Servlet項(xiàng)目轉(zhuǎn)換為Spring Boot項(xiàng)目

    如何將JSP/Servlet項(xiàng)目轉(zhuǎn)換為Spring Boot項(xiàng)目

    這篇文章主要介紹了如何將JSP/Servlet項(xiàng)目轉(zhuǎn)換為Spring Boot項(xiàng)目,幫助大家更好的利用springboot進(jìn)行網(wǎng)絡(luò)編程,感興趣的朋友可以了解下
    2020-10-10
  • Spring Security認(rèn)證提供程序示例詳解

    Spring Security認(rèn)證提供程序示例詳解

    這篇文章主要給大家介紹了關(guān)于Spring Security認(rèn)證提供程序的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Security具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • SpringBoot整合liquibase的實(shí)現(xiàn)方法

    SpringBoot整合liquibase的實(shí)現(xiàn)方法

    這篇文章主要介紹了SpringBoot整合liquibase的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java通過(guò)匿名類來(lái)實(shí)現(xiàn)回調(diào)函數(shù)實(shí)例總結(jié)

    Java通過(guò)匿名類來(lái)實(shí)現(xiàn)回調(diào)函數(shù)實(shí)例總結(jié)

    這篇文章主要介紹了Java通過(guò)匿名類來(lái)實(shí)現(xiàn)回調(diào)函數(shù)的例子,回調(diào)函數(shù)就是一種函數(shù)簽名(若干個(gè)輸入?yún)?shù)、一個(gè)輸出參數(shù))的規(guī)范,java雖不存在函數(shù)聲明,但是java可以用接口來(lái)強(qiáng)制規(guī)范。具體操作步驟大家可查看下文的詳細(xì)講解,感興趣的小伙伴們可以參考一下。
    2017-08-08
  • java多線程編程之慎重使用volatile關(guān)鍵字

    java多線程編程之慎重使用volatile關(guān)鍵字

    volatile關(guān)鍵字相信了解Java多線程的讀者都很清楚它的作用。volatile關(guān)鍵字用于聲明簡(jiǎn)單類型變量,下面看一下為什么要慎重使用volatile關(guān)鍵字
    2014-01-01
  • Jenkins配置ssh私鑰全過(guò)程

    Jenkins配置ssh私鑰全過(guò)程

    文章介紹了在Jenkins上配置SSH私鑰憑證的步驟,包括找到憑證管理、選擇Jenkins、進(jìn)入全局憑據(jù)、添加憑據(jù)、填寫配置信息(如SSH用戶名和私鑰)等步驟
    2026-02-02
  • SpringBoot中熱部署配置深入講解原理

    SpringBoot中熱部署配置深入講解原理

    在實(shí)際開發(fā)中,每次修改代碼就需要重啟項(xiàng)目,重新部署,對(duì)于一個(gè)后端開發(fā)者來(lái)說(shuō),重啟確實(shí)很難受。在java開發(fā)領(lǐng)域,熱部署一直是一個(gè)難以解決的問(wèn)題,目前java虛擬機(jī)只能實(shí)現(xiàn)方法體的熱部署,對(duì)于整個(gè)類的結(jié)構(gòu)修改,仍然需要重啟項(xiàng)目
    2023-01-01
  • Java獲取服務(wù)器狀態(tài)之CPU、內(nèi)存、存儲(chǔ)等核心信息監(jiān)控全攻略

    Java獲取服務(wù)器狀態(tài)之CPU、內(nèi)存、存儲(chǔ)等核心信息監(jiān)控全攻略

    作為一名剛?cè)胄械腏ava開發(fā)者,了解如何獲取服務(wù)器的CPU和內(nèi)存使用情況是一項(xiàng)基本技能,這篇文章主要介紹了Java獲取服務(wù)器狀態(tài)之CPU、內(nèi)存、存儲(chǔ)等核心信息監(jiān)控的相關(guān)資料,需要的朋友可以參考下
    2026-04-04
  • Java非法字符: ‘\ufeff‘問(wèn)題及說(shuō)明

    Java非法字符: ‘\ufeff‘問(wèn)題及說(shuō)明

    這篇文章主要介紹了Java非法字符: ‘\ufeff‘問(wèn)題及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評(píng)論

南部县| 苏州市| 沅江市| 旬邑县| 淮北市| 淮安市| 清河县| 乌拉特前旗| 楚雄市| 尼木县| 竹溪县| 广平县| 永福县| 天台县| 庄河市| 迁安市| 华容县| 东光县| 黄冈市| 峨山| 荔浦县| 平泉县| 雅江县| 洮南市| 定西市| 泰来县| 嘉禾县| 中宁县| 山阴县| 金乡县| 措美县| 五原县| 浏阳市| 腾冲县| 三河市| 灌南县| 仙桃市| 永川市| 甘孜| 苏尼特左旗| 霍州市|