mybatis?<foreach>標(biāo)簽動(dòng)態(tài)增刪改查方式
<foreach>標(biāo)簽動(dòng)態(tài)增刪改查
mybatis<foreach>
有的時(shí)候在項(xiàng)目中需要查詢某個(gè)列表時(shí),可能會(huì)在代碼中進(jìn)行嵌套循環(huán)再取值,其實(shí)mybatis提供了這么一個(gè)標(biāo)簽,可以在SQL中進(jìn)行循環(huán)(是不是很酸爽)
先來了解一下foreach這個(gè)標(biāo)簽有哪些元素:
item
:表示集合中每一個(gè)元素進(jìn)行迭代時(shí)的別名index
:指定一個(gè)名字,用于表示在迭代過程中,每次迭代到的位置open
:表示該語句以什么開始separator
:表示在每次進(jìn)行迭代之間以什么符號(hào)作為分隔符close
:表示以什么結(jié)束collection
:被循環(huán)的集合或者數(shù)組
注意:
在使用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或者Object。
實(shí)戰(zhàn)
話不多說,看代碼,首先是mybatis的XML如何寫,拿動(dòng)態(tài)創(chuàng)建表為例子,什么是動(dòng)態(tài)創(chuàng)建表,就是可以隨便生成表名,字段是傳入進(jìn)來的集合數(shù)組,根據(jù)這個(gè)數(shù)組內(nèi)容來創(chuàng)建字段
<update id="createTable" parameterType="java.util.HashMap"> ? ? ? ? CREATE TABLE IF NOT EXISTS ed_temp_${tableName}( ? ? ? ? id VARCHAR(32) NOT NULL, ? ? ? ? log_id VARCHAR(32), ? ? ? ? state INT, ? ? ? ? message VARCHAR(255) ? ? ? ? <foreach collection="list" item="column" open="," separator="VARCHAR(255)," ? ? ? ? ? ? ? ? ?close="VARCHAR(255), PRIMARY KEY (id)"> ? ? ? ? ? ? ${column.name} ? ? ? ? </foreach> ? ? ? ? ) ENGINE = InnoDB DEFAULT CHARSET = utf8; ? ? </update>
這個(gè)<foreach>看出,我傳入的叫一個(gè)list的集合,別名叫column,從,開始,因?yàn)樯厦鎚essage少個(gè)逗號(hào),中間用VARCHAR(255),做分隔符,已什么為結(jié)束都定義好了。
看Mapper類
/** ? ? ?* 動(dòng)態(tài)創(chuàng)建表 ? ? ?*/ ? ? void createTable(HashMap<String , Object> map);
看實(shí)現(xiàn)
? ? /** ? ? ?* 創(chuàng)建表 ? ? ?* @param templateId 模板id ? ? ?*/ ? ? private void createTable(String templateId){ ? ? ? ? List<EdTemplateField> fields = edTemplateFieldMapper.findByTemplate(templateId); ? ? ? ? List<EdFieldColumns> columns = new ArrayList<>(); ? ? ? ? HashMap<String,Object> map = new HashMap<>(16); ? ? ? ? map.put("tableName",templateId); ? ? ? ? for (EdTemplateField field : fields) { ? ? ? ? ? ? columns.add(edFieldColumnsMapper.findByField(field.getId()).get(0)); ? ? ? ? } ? ? ? ? map.put("list",columns); ? ? ? ? edTemplateMapper.createTable(map); ? ? }
邏輯是這樣的,通過傳入的ID,去尋找所需要的值,再創(chuàng)建一個(gè)List和一個(gè)Map,將表名放進(jìn)來,在將需要的數(shù)組放進(jìn)來,調(diào)用mapper的方法,最后就能成功創(chuàng)建一張動(dòng)態(tài)表
往這個(gè)動(dòng)態(tài)表里插入數(shù)據(jù)的方式也用到了<foreach>,應(yīng)該說不得不用,不然怎么插入,又不知道表名又沒有實(shí)體類
XML
? ? <insert id="tableInsert" parameterType="java.util.HashMap"> ? ? ? ? INSERT INTO ed_temp_${tableName}( ? ? ? ? id,log_id,state,message ? ? ? ? <foreach collection="columns" item="column" open="," separator="," > ? ? ? ? ? ? ${column.name} ? ? ? ? </foreach> ? ? ? ? )VALUES( ? ? ? ? <foreach collection="values" item="value" open="REPLACE(UUID(),'-','')," separator="," > ? ? ? ? ? ? #{value} ? ? ? ? </foreach> ? ? ? ? ) ? ? </insert>
兩個(gè)<foreach>標(biāo)簽,一個(gè)是字段,剛剛那個(gè)動(dòng)態(tài)建表的字段,一個(gè)是值
mapper類
/** ? ? ?* 動(dòng)態(tài)插入 ? ? ?* @param map ? ? ?*/ ? ? void tableInsert(HashMap<String,Object> map);
實(shí)現(xiàn)方法
/** ? ? ?* 保存數(shù)據(jù)到臨時(shí)表 ? ? ?* @param templateId 模板id ? ? ?* @param list 數(shù)據(jù)集合 ? ? ?* @param hearTitle 數(shù)據(jù)對應(yīng)的字段 ? ? ?*/ ? ? private void tableInsert(String templateId,List<String> list,List<String> hearTitle){ ? ? ? ? ?List<EdFieldColumns> columns = new ArrayList<>(); ? ? ? ? HashMap<String,Object> map = new HashMap<>(16); ? ? ? ? map.put("tableName",templateId); ? ? ? ? for (String s : hearTitle) { ? ? ? ? ? ? columns.add(edFieldColumnsMapper.findByTemplateIdAndName(s,templateId)); ? ? ? ? } ? ? ? ? map.put("columns",columns); ? ? ? ? map.put("values",list); ? ? ? ? edTemplateMapper.tableInsert(map); ? ? }
說明
其余的類代碼就不貼了,邏輯是這樣的,創(chuàng)建一個(gè)放字段的集合和傳入的map,集合的值必須要和字段對應(yīng)的上,不然插錯(cuò)字段值那就很尷尬,所以必須要通過動(dòng)態(tài)創(chuàng)建的字段和值的順序是一樣的,比如第一個(gè)創(chuàng)建了name那插入的第一個(gè)就是name,這個(gè)意思,所以這里是根據(jù)順序,先排好了字段,放入map里,再將要放入動(dòng)態(tài)表的值放進(jìn)來,進(jìn)行mapper操作
有了建表以及插入,當(dāng)然少不了刪除和更新
刪除表的xml
<update id="deleteTable" parameterType="java.lang.String"> ? ? DROP TABLE ${tempTable} </update> <delete id="deleteTemporary"> ? ? ? ? DELETE ? ? ? ? FROM ? ? ? ? ? ? ?${tableName} ? ? ? ? WHERE ? ? ? ? ? ? id = #{id} ? ? </delete>
用于來刪除不需要的表,以及刪除數(shù)據(jù)
void deleteTable(@param(value = "tempTable") String tempTable); void deleteTemporary(@Param("tableName") String tableName, ? ? ? ? ? ? ? ? ? ? ? ? ?@Param("id") String id);
這是mapper接口的寫法,傳入要?jiǎng)h除的表名就可以
更新的XML
<update id="updateTemporary"> ? ? ? ? UPDATE ${tableName} ? ? ? ? SET ? ? ? ? <foreach collection="dataMap" index="key" item="value" ?separator="," > ? ? ? ? ? ? ${key} = #{value} ? ? ? ? </foreach> ? ? ? ? WHERE ? ? ? ? ? ? id = #{id} ? ? </update>
對應(yīng)的mapper接口
?void updateTemporary(@Param("tableName") String tableName, ? ? ? ? ? ? ? ? ? ? ? ? ?@Param("id") String id, ? ? ? ? ? ? ? ? ? ? ? ? ?@Param("dataMap") HashMap dataMap);
mapper.xml中<foreach>標(biāo)簽使用
循環(huán)參數(shù)內(nèi)容,還具備在內(nèi)容的前后添加內(nèi)容,還具備添加分隔符功能。
適用場景
in 查詢.批量新增中(mybatis 中 foreach 效率比較低)
1 如果希望批量新增,SQL 命令
insert into tableName VALUES (default,1,2,3),(default,4,5,6),(default,7,8,9)
2 openSession()必須指定底層 JDBC 的
PreparedStatement.addBatch();??? factory.openSession(ExecutorType.BATCH);
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- MyBatis使用<foreach>標(biāo)簽like查詢報(bào)錯(cuò)解決問題
- MyBatis使用<foreach>標(biāo)簽報(bào)錯(cuò)問題及解決
- Mybatis使用foreach標(biāo)簽實(shí)現(xiàn)批量插入方式
- MyBatis之foreach標(biāo)簽的用法及多種循環(huán)問題
- 關(guān)于MyBatis的foreach標(biāo)簽常用方法
- MyBatis中foreach標(biāo)簽的collection屬性的取值方式
- mybatis中foreach嵌套if標(biāo)簽方式
- Mybatis之foreach標(biāo)簽內(nèi)傳入list為空的問題
相關(guān)文章
Hibernate中實(shí)現(xiàn)增刪改查的步驟詳解
本篇文章主要介紹了Hibernate中實(shí)現(xiàn)增刪改查的步驟與方法,具有很好的參考價(jià)值,下面跟著小編一起來看下吧2017-02-02Java微信公眾平臺(tái)開發(fā)(15) 微信JSSDK的使用
這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺(tái)開發(fā)第十五步,微信JSSDK的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04Spring WebFlux使用函數(shù)式編程模型構(gòu)建異步非阻塞服務(wù)
這篇文章主要介紹了Spring WebFlux使用函數(shù)式編程模型構(gòu)建異步非阻塞服務(wù),重點(diǎn)介紹如何使用函數(shù)式編程模型創(chuàng)建響應(yīng)式 RESTful 服務(wù),這種編程模型與傳統(tǒng)的基于 Spring MVC 構(gòu)建 RESTful 服務(wù)的方法有較大差別,感興趣的朋友跟隨小編一起看看吧2023-08-08springcloud?feign服務(wù)之間調(diào)用,date類型轉(zhuǎn)換錯(cuò)誤的問題
這篇文章主要介紹了springcloud?feign服務(wù)之間調(diào)用,date類型轉(zhuǎn)換錯(cuò)誤的問題及解決,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Java實(shí)現(xiàn)學(xué)生成績輸出到磁盤文件的方法詳解
這篇文章主要為大家詳細(xì)介紹了如何利用Java實(shí)現(xiàn)將學(xué)生成績輸出到磁盤文件的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-11-11Spring MVC獲取查詢參數(shù)及路徑參數(shù)代碼實(shí)例
這篇文章主要介紹了Spring MVC獲取查詢參數(shù)及路徑參數(shù)代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02SpringBoot中maven項(xiàng)目打成war包部署在linux服務(wù)器上的方法
這篇文章主要介紹了SpringBoot中maven項(xiàng)目打成war包部署在linux服務(wù)器上的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05