亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Mybatis-plus自動(dòng)填充不生效或自動(dòng)填充數(shù)據(jù)為null原因及解決方案

 更新時(shí)間:2022年05月17日 16:30:36   作者:五更依舊朝花落  
本文主要介紹了Mybatis-plus自動(dòng)填充不生效或自動(dòng)填充數(shù)據(jù)為null原因及解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

昨天使用mybatis-plus。使用自動(dòng)填充后發(fā)現(xiàn)了兩個(gè)問(wèn)題。

  • 一個(gè)是填充數(shù)據(jù)為null,
  • 一個(gè)是當(dāng)使用了mybatis-plus的樂(lè)觀鎖,自動(dòng)填充就失效了

開(kāi)始在網(wǎng)上看,有人說(shuō)是mybatis的bug,我想不會(huì)我這么快就遇到了bug。后面我通過(guò)idea的(ctrl+B)看他的源碼.發(fā)現(xiàn)這不是bug,而是一個(gè)非常巧妙的設(shè)計(jì),當(dāng)然也可能是之前有bug,我用的版本是正常的

mybatis官網(wǎng)自動(dòng)填充功能說(shuō)明
我使用的版本是3.3.2

如果想省時(shí)間,前面的問(wèn)題描述和分析過(guò)程不用看,直接根據(jù)目錄跳到小結(jié)就好了。

問(wèn)題一:自動(dòng)填充的數(shù)據(jù)為null

原因:[填充的數(shù)據(jù)類(lèi)型] 和 [實(shí)體類(lèi)定義的數(shù)據(jù)類(lèi)型] 不一致。例如你的updateTime是 java.util.Date類(lèi)型的。但是填充的是LocalDateTime(因?yàn)楣倬W(wǎng)給個(gè)就是這個(gè),可能就是直接用了)。這就會(huì)導(dǎo)致填充的數(shù)據(jù)為空。

參考如下定義

this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());

以下是官網(wǎng)給的示范:(我把那兩個(gè)過(guò)期方法去掉了)

@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

? ? @Override
? ? public void insertFill(MetaObject metaObject) {
? ? ? ? log.info("start insert fill ....");
? ? ? ? this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推薦使用)
? ? ? ? this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 該方法有bug請(qǐng)升級(jí)到之后的版本如`3.3.1.8-SNAPSHOT`)
? ? ? ? /* 上面選其一使用,下面的已過(guò)時(shí)(注意 strictInsertFill 有多個(gè)方法,詳細(xì)查看源碼) */
? ? ? ?
? ? }

? ? @Override
? ? public void updateFill(MetaObject metaObject) {
? ? ? ? log.info("start update fill ....");
? ? ? ? this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推薦使用)
? ? ? ? this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 該方法有bug請(qǐng)升級(jí)到之后的版本如`3.3.1.8-SNAPSHOT`)
? ? ? ? /* 上面選其一使用,下面的已過(guò)時(shí)(注意 strictUpdateFill 有多個(gè)方法,詳細(xì)查看源碼) */
? ? }
}

問(wèn)題二:使用mybatis-plus的樂(lè)觀鎖后發(fā)現(xiàn)自動(dòng)填充的updateTime字段不自動(dòng)填充了

該問(wèn)題還有其他描述:從數(shù)據(jù)庫(kù)查出來(lái)的數(shù)據(jù),無(wú)法進(jìn)行自動(dòng)填充

本質(zhì)原因:當(dāng)該字段有值之后,自動(dòng)填充不進(jìn)行填充,里面的數(shù)據(jù)還是原值

下面兩段代碼,testUpdateUser和testOptimisticLocker。前者updateTime進(jìn)行了自動(dòng)填充,后者沒(méi)有進(jìn)行自動(dòng)填充。

原因是后者的User對(duì)象所有字段的值都從數(shù)據(jù)庫(kù)查出來(lái),并進(jìn)行了賦值。然后自動(dòng)填充數(shù)據(jù)沒(méi)有填充數(shù)據(jù)

示例:

    @Test
    public void testUpdateUser(){
        User user = new User();
        user.setId(7L);
        user.setName("喻文波");
        int rows = userMapper.updateById(user);
        System.out.println(rows);
    }
    /**
     * 測(cè)試樂(lè)觀鎖
     */
    @Test
    public void testOptimisticLocker(){
        // 先查詢(xún)一個(gè)用戶(hù)
        User user = userMapper.selectById(8L);
        System.out.println(user);
        // 修改用戶(hù)觀察version是否更新
        user.setName("pdd");
        user.setEmail("PDD@163.com");
        int rows = userMapper.updateById(user);
        System.out.println(rows);
    }

原因:

填充用的方法是:this.fillStrategy(metaObject,"updateTime",new Date());,這是官網(wǎng)提供的方法之一
我們ctrl+B進(jìn)去看下

default MetaObjectHandler fillStrategy(MetaObject metaObject, String fieldName, Object fieldVal) {
? ? ? ? if (this.getFieldValByName(fieldName, metaObject) == null) {
? ? ? ? ? ? this.setFieldValByName(fieldName, fieldVal, metaObject);
? ? ? ? }

? ? ? ? return this;
? ? }

發(fā)現(xiàn)就是故意這樣設(shè)計(jì)的,當(dāng)你要填充的字段 fieldName對(duì)應(yīng)的字段為空時(shí)才進(jìn)行自動(dòng)填充,否則不進(jìn)行填充
然后我又看了官網(wǎng)提供的另一個(gè)方法this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
ctrl+B 看下源碼

最終調(diào)用的是下面這個(gè)。有點(diǎn)長(zhǎng)。一看就不想看

然后我strict的意思,嚴(yán)格的。我推測(cè)這個(gè)應(yīng)該就是說(shuō)強(qiáng)制執(zhí)行的意思,不管是否有原值都強(qiáng)制執(zhí)行更新。然后我試了下,果然就是這樣的

? ? default MetaObjectHandler strictFill(boolean insertFill, TableInfo tableInfo, MetaObject metaObject, List<StrictFill> strictFills) {
? ? ? ? if (insertFill && tableInfo.isWithInsertFill() || !insertFill && tableInfo.isWithUpdateFill()) {
? ? ? ? ? ? strictFills.forEach((i) -> {
? ? ? ? ? ? ? ? String fieldName = i.getFieldName();
? ? ? ? ? ? ? ? tableInfo.getFieldList().stream().filter((j) -> {
? ? ? ? ? ? ? ? ? ? return j.getProperty().equals(fieldName) && i.getFieldType().equals(j.getPropertyType()) && (insertFill && j.isWithInsertFill() || !insertFill && j.isWithUpdateFill());
? ? ? ? ? ? ? ? }).findFirst().ifPresent((j) -> {
? ? ? ? ? ? ? ? ? ? this.strictFillStrategy(metaObject, fieldName, i.getFieldVal());
? ? ? ? ? ? ? ? });
? ? ? ? ? ? });
? ? ? ? }

? ? ? ? return this;
? ? }

最后總結(jié):
insert也是一樣的。

? ?@Override
? ? public void updateFill(MetaObject metaObject) {
? ? ? ? // 如果有值,則不會(huì)更新
? ? ? ?// this.fillStrategy(metaObject,"updateTime",new Date());
? ? ? ? // 即使有值,也更新為當(dāng)前時(shí)間
? ? ? ?this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());

? ? }

小結(jié)

填充的方法一共有三個(gè)

// 這個(gè)是通用的,插入和更新都可以使用 但是當(dāng)字段存在值 的時(shí)候不進(jìn)行填充
this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 該方法有bug請(qǐng)升級(jí)到之后的版本如`3.3.1.8-SNAPSHOT`)
// 這個(gè)是insert的時(shí)候用的,插入的時(shí)候時(shí)候強(qiáng)制進(jìn)行填充
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推薦使用)
// update的時(shí)候使用,更新的時(shí)候強(qiáng)制進(jìn)行填充
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推薦使用)

注意填充的類(lèi)型,要和你定義字段的類(lèi)型一致,不然就可能出現(xiàn)填充為為空值的情況 例如原值是java.util.Date ,填充的LocalDateTime就會(huì)出現(xiàn)這種情況

到此這篇關(guān)于Mybatis-plus自動(dòng)填充不生效或自動(dòng)填充數(shù)據(jù)為null原因及解決方案的文章就介紹到這了,更多相關(guān)Mybatis-plus自動(dòng)填充內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java多線程編程之使用Synchronized塊同步變量

    java多線程編程之使用Synchronized塊同步變量

    我們可以通過(guò)synchronized塊來(lái)同步特定的靜態(tài)或非靜態(tài)方法。要想實(shí)現(xiàn)這種需求必須為這些特性的方法定義一個(gè)類(lèi)變量,然后將這些方法的代碼用synchronized塊括起來(lái),并將這個(gè)類(lèi)變量作為參數(shù)傳入synchronized塊
    2014-01-01
  • 關(guān)于postman傳參的幾種格式 list,map 等

    關(guān)于postman傳參的幾種格式 list,map 等

    這篇文章主要介紹了postman傳參的幾種格式 list,map等,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • JAVA實(shí)現(xiàn)301永久重定向方法

    JAVA實(shí)現(xiàn)301永久重定向方法

    本篇文章給大家總結(jié)了JAVA中實(shí)現(xiàn)永久重定向的方法以及詳細(xì)代碼,對(duì)此有需要的朋友可以參考學(xué)習(xí)下。
    2018-04-04
  • 如何基于http代理解決Java固定ip問(wèn)題

    如何基于http代理解決Java固定ip問(wèn)題

    這篇文章主要介紹了如何基于http代理解決Java固定ip問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java Socket實(shí)現(xiàn)簡(jiǎn)易聊天室

    Java Socket實(shí)現(xiàn)簡(jiǎn)易聊天室

    這篇文章主要為大家詳細(xì)介紹了Java Socket實(shí)現(xiàn)簡(jiǎn)易聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • 深入了解Java GC的工作原理

    深入了解Java GC的工作原理

    下面小編就為大家?guī)?lái)一篇深入了解Java GC的工作原理。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-06-06
  • 寶塔升級(jí)JDK版本超詳細(xì)圖文教程

    寶塔升級(jí)JDK版本超詳細(xì)圖文教程

    寶塔自動(dòng)安裝的JDK是一種用于開(kāi)發(fā)和運(yùn)行Java程序的軟件開(kāi)發(fā)工具包,下面這篇文章主要給大家介紹了關(guān)于寶塔升級(jí)JDK版本的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • Spring Boot整合Spring Cache及Redis過(guò)程解析

    Spring Boot整合Spring Cache及Redis過(guò)程解析

    這篇文章主要介紹了Spring Boot整合Spring Cache及Redis過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Java視頻格式轉(zhuǎn)化的實(shí)現(xiàn)方法

    Java視頻格式轉(zhuǎn)化的實(shí)現(xiàn)方法

    這篇文章主要為大家詳細(xì)介紹了Java視頻格式轉(zhuǎn)化的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • java如何刪除以逗號(hào)隔開(kāi)的字符串中某一個(gè)值

    java如何刪除以逗號(hào)隔開(kāi)的字符串中某一個(gè)值

    這篇文章主要介紹了java如何刪除以逗號(hào)隔開(kāi)的字符串中某一個(gè)值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06

最新評(píng)論