电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Fluent Mybatis 批量更新的使用

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

背景描述

通常需要一次更新多條數據有兩個方式

在業務代碼中循環遍歷,逐條更新一次性更新所有數據, 采用批量sql方式,一次執行。

更準確的說是一條sql語句來更新所有數據,逐條更新的操作放到數據庫端,在業務代碼端展現的就是一次性更新所有數據。

這兩種方式各有利弊,程序中for循環實現就不說了,這里主要介紹第二種方式在fluent mybatis中的實現,以及和mybatis實現的對比。

java中for循環實現方式

public class UpdateBatchTest extends BaseTest { @Autowired private StudentMapper mapper; @Test public void testBatchJavaEach() {/** 構造多個更新 **/List<IUpdate> updates = this.newListUpdater();for (IUpdate update : updates) { mapper.updateBy(update);} }/** * 構造多個更新操作 */ 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); }}

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

一條SQL,服務端逐條更新mybatis實現方式

通過mybatis提供的循環標簽,一次構造多條update的sql,一次提交服務器進行執行。

<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);}

執行測試驗證

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);/** 驗證SQL參數 **/db.table(ATM.table.student).query().eqDataMap(ATM.dataMap.student.table(2) .id.values(23L, 24L) .userName.values('user name23', 'user name24')); }}使用FluentMybatis實現方式

使用fluent mybatis進行批量更新很簡單,只需要在#updateBy方法中傳入 IUpdate數組即可

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);/** 驗證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);/** 驗證SQL參數 **/db.table(ATM.table.student).query().eqDataMap(ATM.dataMap.student.table(2) .id.values(23L, 24L) .userName.values('user name23', 'user name24')); }}

要實現批量更新,首先得設置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語法實現的批量更新3條記錄,并且根據id的值不同,設置不同的address值。

mybatis原生實現方式

如果使用mybatis的xml語法來實現,xml文件就需要表達為下面方式:

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);}

驗證

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)));/** 驗證執行的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實現方式

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);/** 驗證執行的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語句,和對應的參數(對應case when語句中的預編譯占位符’?’)

如果業務入口傳入的是Entity List或者Map List,可以使用java8的stream功能處理成數組,示例如下:

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);// 驗證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);// 驗證參數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文件就夠了)。在業務邏輯上不至于因為有額外的xml文件,而產生割裂感。

批量更新不同的表數據

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

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

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();/** 執行不同表的批量更新 **/mapper.updateBy(update1, update2); /** 驗證實際執行的預編譯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'));/** 驗證實際執行預編譯SQL入參值 **/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文檔

到此這篇關于Fluent Mybatis 批量更新的使用的文章就介紹到這了,更多相關Fluent Mybatis 批量更新內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Mybatis 數據庫
相關文章:
主站蜘蛛池模板: 排烟防火阀-消防排烟风机-正压送风口-厂家-价格-哪家好-德州鑫港旺通风设备有限公司 | 深圳货架厂_仓库货架公司_重型仓储货架_线棒货架批发-深圳市诺普泰仓储设备有限公司 | 艾默生变频器,艾默生ct,变频器,ct驱动器,广州艾默生变频器,供水专用变频器,风机变频器,电梯变频器,艾默生变频器代理-广州市盟雄贸易有限公司官方网站-艾默生变频器应用解决方案服务商 | 沈阳激光机-沈阳喷码机-沈阳光纤激光打标机-沈阳co2激光打标机 | 网站建设-高端品牌网站设计制作一站式定制_杭州APP/微信小程序开发运营-鼎易科技 | 便民信息网_家电维修,家电清洗,开锁换锁,本地家政公司 | 英思科GTD-3000EX(美国英思科气体检测仪MX4MX6)百科-北京嘉华众信科技有限公司 | 船老大板材_浙江船老大全屋定制_船老大官网| 气动隔膜泵-电动隔膜泵-循环热水泵-液下排污/螺杆/管道/化工泵「厂家」浙江绿邦 | 小青瓦丨古建筑瓦丨青瓦厂家-宜兴市徽派古典建筑材料有限公司 | 西宁装修_西宁装修公司-西宁业之峰装饰-青海业之峰墅级装饰设计公司【官网】 | 爆破器材运输车|烟花爆竹运输车|1-9类危险品厢式运输车|湖北江南专用特种汽车有限公司 | 拉力机-万能试验机-材料拉伸试验机-电子拉力机-拉力试验机厂家-冲击试验机-苏州皖仪实验仪器有限公司 | 818手游网_提供当下热门APP手游_最新手机游戏下载 | 食品机械专用传感器-落料放大器-低价接近开关-菲德自控技术(天津)有限公司 | 广东教师资格网-广东教师资格证考试网| 减速机电机一体机_带电机减速器一套_德国BOSERL电动机与减速箱生产厂家 | 真空包装机-诸城市坤泰食品机械有限公司| 全自动不干胶贴标机_套标机-上海今昂贴标机生产厂家 | 便携式谷丙转氨酶检测仪|华图生物科技百科 | 冷却塔减速机器_冷却塔皮带箱维修厂家_凉水塔风机电机更换-广东康明冷却塔厂家 | 西安标准厂房_陕西工业厂房_西咸新区独栋厂房_长信科技产业园官方网站 | 玻璃钢罐_玻璃钢储罐_盐酸罐厂家-河北华盛节能设备有限公司 | 合肥白癜风医院_[治疗白癜风]哪家好_合肥北大白癜风医院 | 无锡网站建设_小程序制作_网站设计公司_无锡网络公司_网站制作 | 电动手术床,医用护理床,led手术无影灯-曲阜明辉医疗设备有限公司 | TPU薄膜_TPU薄膜生产厂家_TPU热熔胶膜厂家定制_鑫亘环保科技(深圳)有限公司 | 煤棒机_增碳剂颗粒机_活性炭颗粒机_木炭粉成型机-巩义市老城振华机械厂 | pos机办理,智能/扫码/二维码/微信支付宝pos机-北京万汇通宝商贸有限公司 | 汽车整车综合环境舱_军标砂尘_盐雾试验室试验箱-无锡苏南试验设备有限公司 | 天一线缆邯郸有限公司_煤矿用电缆厂家_矿用光缆厂家_矿用控制电缆_矿用通信电缆-天一线缆邯郸有限公司 | 圆形振动筛_圆筛_旋振筛_三次元振动筛-河南新乡德诚生产厂家 | 整合营销推广|营销网络推广公司|石家庄网站优化推广公司|智营销 好物生环保网、环保论坛 - 环保人的学习交流平台 | 杭州双螺杆挤出机-百科 | 无线联网门锁|校园联网门锁|学校智能门锁|公租房智能门锁|保障房管理系统-KEENZY中科易安 | 变频器维修公司_plc维修_伺服驱动器维修_工控机维修 - 夫唯科技 变位机,焊接变位机,焊接变位器,小型变位机,小型焊接变位机-济南上弘机电设备有限公司 | 不锈钢复合板|钛复合板|金属复合板|南钢集团安徽金元素复合材料有限公司-官网 | 碳刷_刷握_集电环_恒压簧_电刷厂家-上海丹臻机电科技有限公司 | 广州中央空调回收,二手中央空调回收,旧空调回收,制冷设备回收,冷气机组回收公司-广州益夫制冷设备回收公司 | 磁力抛光研磨机_超声波清洗机厂家_去毛刺设备-中锐达数控 | 电磁流量计厂家_涡街流量计厂家_热式气体流量计-青天伟业仪器仪表有限公司 |