" />

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

mybatis-plus調(diào)用update方法時(shí),自動(dòng)填充字段不生效問(wèn)題及解決

 更新時(shí)間:2024年06月05日 10:59:54   作者:遠(yuǎn)離bug,珍愛(ài)頭發(fā)  
這篇文章主要介紹了mybatis-plus調(diào)用update方法時(shí),自動(dòng)填充字段不生效問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

項(xiàng)目場(chǎng)景

做定時(shí)任務(wù),查詢出數(shù)據(jù)后,將他發(fā)往mq隊(duì)列,如果搭建集群相同的數(shù)據(jù)就會(huì)執(zhí)行多次,所以使用樂(lè)觀鎖解決,同時(shí)需要更改更新時(shí)間一列,直接使用mybatisPlus的公共字段填充和樂(lè)觀鎖

問(wèn)題描述

配置好mp的樂(lè)觀鎖和公共字段填充后,執(zhí)行update語(yǔ)句,正常應(yīng)該是

UPDATE tb_task SET update_time=?,version=? WHERE (version = ? AND id = ?)

結(jié)果變成了

UPDATE tb_task SET WHERE (version = ? AND id = ?)

因?yàn)槌诉@兩個(gè)字段沒(méi)有其他需要修改的字段所以直接就報(bào)錯(cuò)了,這么一看肯定是樂(lè)觀鎖和公共字段填充都失效了啊。

@Scheduled(cron = "0 0/1 * * * ?")
    public void addCourseTask(){
        //查詢1分鐘之前的數(shù)據(jù)
        List<TbTask> list = tbTaskService.findBeforeMinuteList();
        for (TbTask tbTask : list) {
            //根據(jù)id version修改
            LambdaUpdateWrapper<TbTask> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(TbTask::getId,tbTask.getId());
                    //.set(TbTask::getVersion,tbTask.getVersion()+1);
            //數(shù)據(jù)庫(kù)中的樂(lè)觀鎖, 防止集群下的訂單,重復(fù)向mq中發(fā)送數(shù)據(jù)
            if (tbTaskService.update(wrapper)) {
                String mqExchange = tbTask.getMqExchange();
                String mqRoutingkey = tbTask.getMqRoutingkey();
                //向mq發(fā)送消息
                rabbitTemplate.convertAndSend(mqExchange, mqRoutingkey, JSON.toJSONString(tbTask));

            }


        }
    }

原因分析

檢查了幾遍確定mp的樂(lè)觀鎖和公共字段填充都沒(méi)有問(wèn)題

樂(lè)觀鎖

1.配置樂(lè)觀鎖插件(mp是3.5.1的)

@Configuration
@MapperScan("com.xly.mapper") //掃描mapper接口所在包
public class MybatisPlusConfig {

    @Bean
    //配置分頁(yè)插件
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //分頁(yè)
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        //樂(lè)觀鎖
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;

    }
}

2.字段上打注解

@TableField(value = "version")
    @Version
    private Integer version;

公共字段填充

1.實(shí)現(xiàn)MetaObjectHandler的公共填充類

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    //mp執(zhí)行添加操作,這個(gè)方法執(zhí)行
    @Override
    public void insertFill(MetaObject metaObject) {
        metaObject.setValue("createTime",new Date());
        metaObject.setValue("updateTime",new Date());
    }

    //mp執(zhí)行修改操作,這個(gè)方法執(zhí)行
    @Override
    public void updateFill(MetaObject metaObject) {
        metaObject.setValue("updateTime",new Date());
    }
}

2.在字段上添加fill屬性

@TableField(value = "create_time",fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(value = "update_time",fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

經(jīng)過(guò)查找資料后發(fā)現(xiàn)使用boolean update(Wrapper updateWrapper)這個(gè)方法,自動(dòng)填充會(huì)失效

大概原理就是boolean update(Wrapper updateWrapper)的底層實(shí)現(xiàn)為:

default boolean update(Wrapper<T> updateWrapper) {
        return this.update((Object)null, updateWrapper);
    }

而屬性自動(dòng)填充需要從第一個(gè)參數(shù)獲取Object實(shí)體類,自動(dòng)填充的核心方法:populateKeys中會(huì)判斷

if (null == tableInfo) {
            /* 不處理 */
            return parameterObject;
        }

tableInfo就是獲取的實(shí)體類對(duì)象,所以導(dǎo)致屬性自動(dòng)填充失效。

解決方案

我使用的是上面文章建議的方案一,也是最簡(jiǎn)單的方式:

使用update的重載方法

boolean update(T entity, Wrapper updateWrapper)

修改后的代碼如下:

@Scheduled(cron = "0 0/1 * * * ?")
    public void addCourseTask(){
        //查詢1分鐘之前的數(shù)據(jù)
        List<TbTask> list = tbTaskService.findBeforeMinuteList();
        for (TbTask tbTask : list) {
            //根據(jù)id version修改
            LambdaUpdateWrapper<TbTask> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(TbTask::getId,tbTask.getId());
                    //.set(TbTask::getVersion,tbTask.getVersion()+1);
            //數(shù)據(jù)庫(kù)中的樂(lè)觀鎖, 防止集群下的訂單,重復(fù)向mq中發(fā)送數(shù)據(jù)
            if (tbTaskService.update(tbTask,wrapper)) {
                String mqExchange = tbTask.getMqExchange();
                String mqRoutingkey = tbTask.getMqRoutingkey();
                //向mq發(fā)送消息
                rabbitTemplate.convertAndSend(mqExchange, mqRoutingkey, JSON.toJSONString(tbTask));

            }


        }
    }

執(zhí)行sql語(yǔ)句:

UPDATE tb_task
SET create_time=?, update_time=?, delete_time=?, task_type=?, mq_exchange=?, mq_routingkey=?, request_body=?, status=?, version=? WHERE (version = ? AND id = ?)

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot中熔斷器的原理和使用詳解

    SpringBoot中熔斷器的原理和使用詳解

    這篇文章主要介紹了SpringBoot中熔斷器的原理和使用詳解,熔斷器是一種用于處理分布式系統(tǒng)中故障的設(shè)計(jì)模式,它可以防止出現(xiàn)故障的服務(wù)對(duì)整個(gè)系統(tǒng)造成連鎖反應(yīng),需要的朋友可以參考下
    2023-07-07
  • java棧實(shí)現(xiàn)二叉樹(shù)的非遞歸遍歷的示例代碼

    java棧實(shí)現(xiàn)二叉樹(shù)的非遞歸遍歷的示例代碼

    這篇文章主要介紹了java棧實(shí)現(xiàn)二叉樹(shù)的非遞歸遍歷,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • Java實(shí)現(xiàn)真假隨機(jī)數(shù)詳解

    Java實(shí)現(xiàn)真假隨機(jī)數(shù)詳解

    偽隨機(jī)數(shù)和真隨機(jī)數(shù)是計(jì)算機(jī)科學(xué)和統(tǒng)計(jì)學(xué)中非常重要的概念,理解它們之間的差異有助于選擇合適的隨機(jī)數(shù)生成方案,本文將使用Java實(shí)現(xiàn)真假隨機(jī)數(shù),感興趣的可以了解下
    2024-11-11
  • Spring實(shí)戰(zhàn)之方法級(jí)別緩存用法示例

    Spring實(shí)戰(zhàn)之方法級(jí)別緩存用法示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之方法級(jí)別緩存用法,結(jié)合實(shí)例形式分析了spring方法級(jí)別緩存配置、屬性文件、領(lǐng)域模型及相關(guān)使用技巧,需要的朋友可以參考下
    2020-01-01
  • Java壓縮文件ZIP實(shí)例代碼

    Java壓縮文件ZIP實(shí)例代碼

    這篇文章主要介紹了Java壓縮文件ZIP實(shí)例代碼,有需要的朋友可以參考一下
    2013-12-12
  • Spring?AOP操作的相關(guān)術(shù)語(yǔ)及環(huán)境準(zhǔn)備

    Spring?AOP操作的相關(guān)術(shù)語(yǔ)及環(huán)境準(zhǔn)備

    這篇文章主要為大家介紹了Spring?AOP操作的相關(guān)術(shù)語(yǔ)及環(huán)境準(zhǔn)備學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 學(xué)習(xí)Java內(nèi)存模型JMM心得

    學(xué)習(xí)Java內(nèi)存模型JMM心得

    這篇文章主要介紹了學(xué)習(xí)Java內(nèi)存模型JMM的心得以及對(duì)其原理做了深入的介紹,有興趣的朋友學(xué)習(xí)下吧。
    2017-12-12
  • java 8 lambda表達(dá)式中的異常處理操作

    java 8 lambda表達(dá)式中的異常處理操作

    這篇文章主要介紹了java 8 lambda表達(dá)式中的異常處理操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • 基于Spring BeanUtils的copyProperties方法使用及注意事項(xiàng)

    基于Spring BeanUtils的copyProperties方法使用及注意事項(xiàng)

    這篇文章主要介紹了基于Spring BeanUtils的copyProperties方法使用及注意事項(xiàng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • SpringBoot項(xiàng)目整合mybatis的方法步驟與實(shí)例

    SpringBoot項(xiàng)目整合mybatis的方法步驟與實(shí)例

    今天小編就為大家分享一篇關(guān)于SpringBoot項(xiàng)目整合mybatis的方法步驟與實(shí)例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03

最新評(píng)論

浑源县| 乐至县| 文昌市| 乌拉特前旗| 京山县| 宜君县| 梨树县| 永康市| 关岭| 枣强县| 会宁县| 射洪县| 改则县| 察哈| 长治县| 于田县| 称多县| 台州市| 枝江市| 平昌县| 临洮县| 同仁县| 富蕴县| 宝清县| 六盘水市| 雷波县| 砚山县| 讷河市| 巨野县| 利川市| 永定县| 余姚市| 额尔古纳市| 罗平县| 盐津县| 莎车县| 科技| 商都县| 镇坪县| 米易县| 武川县|