亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術(shù)文章
文章詳情頁

Fluent Mybatis 批量更新的使用

瀏覽:2日期:2023-10-18 11:27:55
目錄批量更新同一張表的數(shù)據(jù)更新多條數(shù)據(jù),每條數(shù)據(jù)都不一樣java中for循環(huán)實(shí)現(xiàn)方式一條SQL,服務(wù)端逐條更新mybatis實(shí)現(xiàn)方式使用FluentMybatis實(shí)現(xiàn)方式使用mysql的Case When then方式更新mybatis原生實(shí)現(xiàn)方式批量更新不同的表數(shù)據(jù)參考批量更新同一張表的數(shù)據(jù)更新多條數(shù)據(jù),每條數(shù)據(jù)都不一樣

背景描述

通常需要一次更新多條數(shù)據(jù)有兩個(gè)方式

在業(yè)務(wù)代碼中循環(huán)遍歷,逐條更新一次性更新所有數(shù)據(jù), 采用批量sql方式,一次執(zhí)行。

更準(zhǔn)確的說是一條sql語句來更新所有數(shù)據(jù),逐條更新的操作放到數(shù)據(jù)庫(kù)端,在業(yè)務(wù)代碼端展現(xiàn)的就是一次性更新所有數(shù)據(jù)。

這兩種方式各有利弊,程序中for循環(huán)實(shí)現(xiàn)就不說了,這里主要介紹第二種方式在fluent mybatis中的實(shí)現(xiàn),以及和mybatis實(shí)現(xiàn)的對(duì)比。

java中for循環(huán)實(shí)現(xiàn)方式

public class UpdateBatchTest extends BaseTest { @Autowired private StudentMapper mapper; @Test public void testBatchJavaEach() {/** 構(gòu)造多個(gè)更新 **/List<IUpdate> updates = this.newListUpdater();for (IUpdate update : updates) { mapper.updateBy(update);} }/** * 構(gòu)造多個(gè)更新操作 */ private List<IUpdate> newListUpdater() {StudentUpdate update1 = new StudentUpdate() .update.userName().is('user name23').end() .where.id().eq(23L).end();StudentUpdate update2 = new StudentUpdate() .update.userName().is('user name24').end() .where.id().eq(24L).end();return Arrays.asList(update1, update2); }}

這種方式在大批量更新時(shí), 最大的問題就是效率,逐條更新,每次都會(huì)連接數(shù)據(jù)庫(kù),然后更新,再釋放連接資源。

一條SQL,服務(wù)端逐條更新mybatis實(shí)現(xiàn)方式

通過mybatis提供的循環(huán)標(biāo)簽,一次構(gòu)造多條update的sql,一次提交服務(wù)器進(jìn)行執(zhí)行。

<update parameterType='java.util.List'> <update parameterType='java.util.List'><foreach collection='list' item='item' index='index' open='' close='' separator=';'> update student <set>user_name=#{item.userName} </set> where id = #{item.id}</foreach> </update> </update>

定義Mapper

public interface StudentBatchMapper { void updateStudentBatch(List list);}

執(zhí)行測(cè)試驗(yàn)證

public class UpdateBatchTest extends BaseTest { @Autowired private StudentBatchMapper batchMapper; @Test public void updateStudentBatch() {List<StudentEntity> students = Arrays.asList( new StudentEntity().setId(23L).setUserName('user name23'), new StudentEntity().setId(24L).setUserName('user name24'));batchMapper.updateStudentBatch(students);/** 驗(yàn)證SQL參數(shù) **/db.table(ATM.table.student).query().eqDataMap(ATM.dataMap.student.table(2) .id.values(23L, 24L) .userName.values('user name23', 'user name24')); }}使用FluentMybatis實(shí)現(xiàn)方式

使用fluent mybatis進(jìn)行批量更新很簡(jiǎn)單,只需要在#updateBy方法中傳入 IUpdate數(shù)組即可

public class UpdateBatchTest extends BaseTest { @Autowired private StudentMapper mapper; @DisplayName('批量更新同一張表') @Test public void testUpdateBatch_same() {IUpdate[] updates = this.newListUpdater().toArray(new IUpdate[0]);mapper.updateBy(updates);/** 驗(yàn)證SQL語句 **/db.sqlList().wantFirstSql().eq('' +'UPDATE student SET gmt_modified = now(), user_name = ? WHERE id = ?; ' +'UPDATE student SET gmt_modified = now(), user_name = ? WHERE id = ?' , StringMode.SameAsSpace);/** 驗(yàn)證SQL參數(shù) **/db.table(ATM.table.student).query().eqDataMap(ATM.dataMap.student.table(2) .id.values(23L, 24L) .userName.values('user name23', 'user name24')); }}

要實(shí)現(xiàn)批量更新,首先得設(shè)置mysql支持批量操作,在jdbc url鏈接中附加&allowMultiQueries=true屬性

例如:

jdbc:mysql://localhost:3306/testdb?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true使用mysql的Case When then方式更新

UPDATE student SET gmt_modified = now(),address = case id when 1 then ’address 1’ when 2 then ’address 2’ when 3 then ’address 3’ endWHERE id in (1, 2, 3)

上面的sql語句使用mysql的case when then語法實(shí)現(xiàn)的批量更新3條記錄,并且根據(jù)id的值不同,設(shè)置不同的address值。

mybatis原生實(shí)現(xiàn)方式

如果使用mybatis的xml語法來實(shí)現(xiàn),xml文件就需要表達(dá)為下面方式:

xml文件

<update parameterType='list'> update student <trim prefix='set' suffixOverrides=','><trim prefix='address =case id' suffix='end,'> <foreach collection='list' item='item' index='index'><if test='item.id!=null'> when #{item.id} then #{item.address}</if> </foreach></trim> </trim> <trim prefix='age =case id' suffix='end,'><foreach collection='list' item='item' index='index'> <if test='item.id!=null'>when #{item.id} then #{item.age} </if></foreach> </trim> where id in <foreach collection='list' item='item' index='index' separator=',' open='(' close=')'>#{item.id} </foreach></update>

定義Mapper

public interface StudentBatchMapper { int updateBatchByIds(List<StudentEntity> list);}

驗(yàn)證

public class CaseFuncTest extends BaseTest { @Autowired private StudentBatchMapper batchMapper; @Test public void test_mybatis_batch() {batchMapper.updateBatchByIds(Arrays.asList( new StudentEntity().setId(1L).setAddress('address 1').setAge(23), new StudentEntity().setId(2L).setAddress('address 2').setAge(24), new StudentEntity().setId(3L).setAddress('address 3').setAge(25)));/** 驗(yàn)證執(zhí)行的SQL語句 **/db.sqlList().wantFirstSql().eq('' +'update student ' +'set address =case id when ? then ? when ? then ? when ? then ? end, ' +'age =case id when ? then ? when ? then ? when ? then ? end ' +'where id in ( ? , ? , ? )' , StringMode.SameAsSpace); }}

使用Fluent Mybatis實(shí)現(xiàn)方式

public class CaseFuncTest extends BaseTest { @Autowired private StudentMapper mapper; @Test public void test_fluentMybatisBatch() throws Exception {final String CaseWhen = 'case id ' + 'when 1 then ? ' + 'when 2 then ? ' + 'else ? end';StudentUpdate update = new StudentUpdate() .update.address().applyFunc(CaseWhen, 'address 1', 'address 2', 'address 3') .set.age().applyFunc(CaseWhen, 23, 24, 25) .end() .where.id().in(new int[]{1, 2, 3}).end();mapper.updateBy(update);/** 驗(yàn)證執(zhí)行的SQL語句 **/db.sqlList().wantFirstSql() .eq('UPDATE student ' + 'SET gmt_modified = now(), ' + 'address = case id when 1 then ? when 2 then ? else ? end, ' + 'age = case id when 1 then ? when 2 then ? else ? end ' + 'WHERE id IN (?, ?, ?)',StringMode.SameAsSpace); }}

只需要在applyFunc中傳入case when語句,和對(duì)應(yīng)的參數(shù)(對(duì)應(yīng)case when語句中的預(yù)編譯占位符’?’)

如果業(yè)務(wù)入口傳入的是Entity List或者M(jìn)ap List,可以使用java8的stream功能處理成數(shù)組,示例如下:

public class CaseFuncTest extends BaseTest { @Autowired private StudentMapper mapper; @Test public void test_fluentMybatisBatch2() throws Exception {List<StudentEntity> students = Arrays.asList( new StudentEntity().setId(1L).setAddress('address 1').setAge(23), new StudentEntity().setId(2L).setAddress('address 2').setAge(24), new StudentEntity().setId(3L).setAddress('address 3').setAge(25));final String CaseWhen = 'case id ' + 'when 1 then ? ' + 'when 2 then ? ' + 'else ? end';StudentUpdate update = new StudentUpdate() .update.address().applyFunc(CaseWhen, getFields(students, StudentEntity::getAddress)) .set.age().applyFunc(CaseWhen, getFields(students, StudentEntity::getAge)) .end() .where.id().in(getFields(students, StudentEntity::getId)).end();mapper.updateBy(update);// 驗(yàn)證SQL語句db.sqlList().wantFirstSql() .eq('UPDATE student ' + 'SET gmt_modified = now(), ' + 'address = case id when 1 then ? when 2 then ? else ? end, ' + 'age = case id when 1 then ? when 2 then ? else ? end ' + 'WHERE id IN (?, ?, ?)',StringMode.SameAsSpace);// 驗(yàn)證參數(shù)db.sqlList().wantFirstPara() .eqReflect(new Object[]{'address 1', 'address 2', 'address 3', 23, 24, 25, 1L, 2L, 3L}); } private Object[] getFields(List<StudentEntity> students, Function<StudentEntity, Object> getField) {return students.stream().map(getField).toArray(Object[]::new); }}

使用Fluent Mybatis無需額外編寫xml文件和mapper(使用框架生成的Mapper文件就夠了)。在業(yè)務(wù)邏輯上不至于因?yàn)橛蓄~外的xml文件,而產(chǎn)生割裂感。

批量更新不同的表數(shù)據(jù)

上面的例子使用mybatis和fluent mybatis演示的如果通過不同方法批量更新同一張表的數(shù)據(jù),在fluent mybatis的更新其實(shí)不限定于同一張表,

在#updateBy(IUpdate... updates)函數(shù)可以傳入任意表更新.

public class UpdateBatchTest extends BaseTest { @Autowired private StudentMapper mapper; @DisplayName('批量更新不同表') @Test public void testUpdateBatch_different() {StudentUpdate update1 = new StudentUpdate() .update.userName().is('user name23').end() .where.id().eq(23L).end();HomeAddressUpdate update2 = new HomeAddressUpdate() .update.address().is('address 24').end() .where.id().eq(24L).end();/** 執(zhí)行不同表的批量更新 **/mapper.updateBy(update1, update2); /** 驗(yàn)證實(shí)際執(zhí)行的預(yù)編譯SQL語句**/db.sqlList().wantFirstSql().eq('' +'UPDATE student SET gmt_modified = now(), user_name = ? WHERE id = ?; ' +'UPDATE home_address SET gmt_modified = now(), address = ? WHERE id = ?', StringMode.SameAsSpace);db.table(ATM.table.student).query().eqDataMap(ATM.dataMap.student.table(2) .id.values(23L, 24L) .userName.values('user name23', 'user'));/** 驗(yàn)證實(shí)際執(zhí)行預(yù)編譯SQL入?yún)⒅?**/db.table(ATM.table.homeAddress).query().eqDataMap(ATM.dataMap.homeAddress.table(2) .id.values(23, 24) .address.values('address', 'address 24')); }}

示例更新了2張表: student 和 home_address

參考

Fluent MyBatis地址Fluent MyBatis文檔

到此這篇關(guān)于Fluent Mybatis 批量更新的使用的文章就介紹到這了,更多相關(guān)Fluent Mybatis 批量更新內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

相關(guān)文章:
主站蜘蛛池模板: 欧美日韩在线精品一区二区三区 | 国产精品美女免费视频观看 | wwwwxxx日本| 91av视频在线免费观看 | 国内精品伊人久久久影视 | 国产视频久久久久 | 一级做性色a爰片久久毛片 一级做性色a爰片久久毛片免费 | 国产欧美亚洲精品综合在线 | 欧美黄色免费在线观看 | 91短视频版在线观看www免费 | 极品主播的慰在线播放 | 欧美性大片免费 | 射狠狠| 亚洲aaaa级特黄毛片 | 久久免费精品国产72精品剧情 | 欧美日韩综合网在线观看 | 九九九九热精品免费视频 | 美女一级大黄录像一片 | 中文激情| 伊人色婷婷| 国产精品久久国产精品99 gif | 免费观看又色又爽又大高清网站 | 国产在线精品一区二区 | 亚洲精品高清国产一线久久97 | 看中国一级毛片 | 精品影院 | 亚洲无毛片 | 精品国产一二三区 | 麻豆国产入口在线观看免费 | 亚洲人成网站999久久久综合 | 老司机51精品视频在线观看 | 欧美在线观看成人高清视频 | 九九视频免费精品视频免费 | 伊人网综合在线视频 | 国产精品欧美亚洲日本综合 | 一级毛片免费在线 | 欧美一区二区三区精品影视 | 三a级片 | 国产乱熟肥女视频网站 | 伊人久久欧美综合精品 | 色片在线观看 |