" />

欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mybatis-plus調用update方法時,自動填充字段不生效問題及解決

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

項目場景

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

問題描述

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

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

結果變成了

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

因為除了這兩個字段沒有其他需要修改的字段所以直接就報錯了,這么一看肯定是樂觀鎖和公共字段填充都失效了啊。

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

            }


        }
    }

原因分析

檢查了幾遍確定mp的樂觀鎖和公共字段填充都沒有問題

樂觀鎖

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

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

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

    }
}

2.字段上打注解

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

公共字段填充

1.實現MetaObjectHandler的公共填充類

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

    //mp執(zhí)行修改操作,這個方法執(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;

經過查找資料后發(fā)現使用boolean update(Wrapper updateWrapper)這個方法,自動填充會失效

大概原理就是boolean update(Wrapper updateWrapper)的底層實現為:

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

而屬性自動填充需要從第一個參數獲取Object實體類,自動填充的核心方法:populateKeys中會判斷

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

tableInfo就是獲取的實體類對象,所以導致屬性自動填充失效。

解決方案

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

使用update的重載方法

boolean update(T entity, Wrapper updateWrapper)

修改后的代碼如下:

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

            }


        }
    }

執(zhí)行sql語句:

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

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Springboot中動態(tài)語言groovy介紹

    Springboot中動態(tài)語言groovy介紹

    Apache的Groovy是Java平臺上設計的面向對象編程語言,這門動態(tài)語言擁有類似Python、Ruby和Smalltalk中的一些特性,可以作為Java平臺的腳本語言使用,這篇文章主要介紹了springboot中如何使用groovy,需要的朋友可以參考下
    2022-09-09
  • idea中的Maven導包失敗問題解決方案匯總

    idea中的Maven導包失敗問題解決方案匯總

    這篇文章主要介紹了idea中的Maven導包失敗問題解決總結,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-02-02
  • idea如何開啟菜單欄

    idea如何開啟菜單欄

    文章介紹了如何通過修改IntelliJ IDEA的樣式文件`ui.lnf.xml`來重新顯示被關閉的菜單欄,并分享了解決問題的步驟
    2025-01-01
  • java正則表達式使用示例

    java正則表達式使用示例

    這篇文章主要介紹了java正則表達式使用示例,實現拆分字符串、替換字符串、判斷字符串是否與制定模式匹配等功能,需要的朋友可以參考下
    2014-03-03
  • SpringBoot中的異常處理與參數校驗的方法實現

    SpringBoot中的異常處理與參數校驗的方法實現

    這篇文章主要介紹了SpringBoot中的異常處理與參數校驗的方法實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • springMVC中的view視圖詳細解析

    springMVC中的view視圖詳細解析

    這篇文章主要介紹了springMVC中的view視圖,springMVC視圖的種類很多,默認有轉發(fā)視圖和重定向視圖,本文就每一種視圖給大家詳細介紹,需要的朋友可以參考下
    2022-03-03
  • SpringBoot+Nacos+Kafka微服務流編排的簡單實現

    SpringBoot+Nacos+Kafka微服務流編排的簡單實現

    本文主要介紹了SpringBoot+Nacos+Kafka微服務流編排的簡單實現,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 基于Properties實現配置數據庫驅動

    基于Properties實現配置數據庫驅動

    這篇文章主要介紹了基于Properties實現配置數據庫驅動,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • 深度解析SpringBoot中@Async引起的循環(huán)依賴

    深度解析SpringBoot中@Async引起的循環(huán)依賴

    本文主要介紹了深度解析SpringBoot中@Async引起的循環(huán)依賴,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Spring Cloud超詳細i講解Feign自定義配置與使用

    Spring Cloud超詳細i講解Feign自定義配置與使用

    這篇文章主要介紹了SpringCloud Feign自定義配置與使用,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06

最新評論