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

深度分析MybatisPlus查詢結果映射失敗@TableField失效解決辦法

 更新時間:2025年07月25日 09:31:58   作者:王ASC  
本文針對SpringBoot使用MybatisPlus框架時出現(xiàn)的查詢結果映射失敗問題進行深入分析,通過源碼解析,闡述了@TableField注解失效的原因,并提出了四種有效的解決方案,感興趣的朋友一起看看吧

問題場景

Springboot使用MybatisPlus框架,數(shù)據(jù)庫中SQL能查到值,但是代碼中查不到,出現(xiàn)All elements are null等問題。以下MybatisPlus簡稱MP

表結構

CREATE TABLE `camel`  (
  `pwd` varchar(255),
  `age` int(11)
);
INSERT INTO `camel` VALUES ('100', 0);
INSERT INTO `camel` VALUES ('200', 1);
INSERT INTO `camel` VALUES ('300', 2);
INSERT INTO `camel` VALUES ('400', NULL);

Java實體類

@TableName(value = "camel")
@Data
public class Camel {
    @TableField("pwd")
    private String pass_word;
    @TableField("age")
    private Integer age;
}

SpringBoot測試類

@SpringBootTest
class DemoApplicationTests {
    @Autowired
    CamelMapper camelMapper;
    @Test
    void testTableField() {
        // 構造查詢條件 pwd > 100 的 LambdaQueryWrapper
        LambdaQueryWrapper<Camel> lambdaQueryWrapper = Wrappers.lambdaQuery(Camel.class)
                .gt(Camel::getPass_word, "100");
        List<Camel> list = camelMapper.selectList(lambdaQueryWrapper);
        list.forEach(System.out::println);
        assert list.get(0).getPass_word()!=null;
    }
}

執(zhí)行結果

代碼執(zhí)行結果與預期不符,數(shù)據(jù)庫中能查詢到pwd,代碼中查到的pass_word為NULL

先說原因

pass_word字段不滿足命名規(guī)范,導致MP框架無法通過反射將查詢字段賦值給實體類屬性。

思考

數(shù)據(jù)從表中到實體類,可以理解為有兩個階段,首先是通過查詢sql得到字段值,然后ORM框架將查詢到的結果集通過setter的方式賦值給接收對象。

@TableField注解,用于使用MP動態(tài)生成SQL或用resultType接受自定義SQL結果集時,解決數(shù)據(jù)庫字段名與實體類的屬性名不一致時的問題,先前認為使用該注解就能結果上述問題。查看源碼中MP給出的注釋,如下

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface TableField {
    /**
     * 數(shù)據(jù)庫字段值
     * <p>
     * 不需要配置該值的情況:
     * <li> 當 {@link com.baomidou.mybatisplus.core.MybatisConfiguration#mapUnderscoreToCamelCase} 為 true 時,
     * (mp下默認是true,mybatis默認是false), 數(shù)據(jù)庫字段值.replace("_","").toUpperCase() == 實體屬性名.toUpperCase() </li>
     * <li> 當 {@link com.baomidou.mybatisplus.core.MybatisConfiguration#mapUnderscoreToCamelCase} 為 false 時,
     * 數(shù)據(jù)庫字段值.toUpperCase() == 實體屬性名.toUpperCase() </li>
     */
    String value() default "";

當使用@TableField注解,執(zhí)行sql如下:

select 注解值 as 實體類屬性名 from table;

@TableField注解是通過別名實現(xiàn)的,其作用是當resultType為實體類時,自動為查詢結果設置別名,是發(fā)生在查詢階段,也因此將控制臺打印的sql拿到數(shù)據(jù)庫中能正常執(zhí)行,而本次問題是發(fā)生在用實體類接收查詢結果階段。

源碼分析

容器啟動后,MP會緩存Mapper實體類的setter與getter方法集合,這里使用了Lombok自動生成setter與getter

開始執(zhí)行查詢方法后,首先預編譯PrepareStatement

當配置了Mybatis或MP的日志實現(xiàn),控制臺會打印預編譯sql與參數(shù),就是在這里實現(xiàn)的

預編譯參數(shù)賦值,這里就是查詢條件中的100

查詢SQL執(zhí)行完成,處理查詢結果的映射關系

根據(jù)是否打開駝峰自動轉換開關,處理屬性名,注意這個開關在Mybatis中是默認關閉,而在MP中是默認打開的!所以在這里的pass_word被替換成了password

之后從容器啟動時MP緩存的實體類的setter與getter方法集合中,查找實體類屬性的setter方法,這里可以找到age,但是pass_word因被駝峰命名替換成password,而實際上實體類中的屬性名是pass_word,導致無法找到password

用實體類中映射成功的字段接收查詢結果,這里就只有age,沒有password了

通過反射執(zhí)行上面找到的屬性的setter方法

只有符合命名規(guī)范的字段才會被賦值成功

最終接收查詢結果的集合size = 3,但集合中只有兩個元素,是因為SQL查出了3條記錄,其中pwd=400的記錄,因password字段賦值失敗為NULL,且age也為NULL,該對象的所有屬性都為NULL,所以集合中就存了一個NULL對象,如果集合中所有元素都是NULL,就會size != 0,且All elements are null

總結

MP通過反射的方式,使用屬性對應setter方法為屬性賦值,將查詢結果映射到實體類,當屬性命名不規(guī)范,且開啟了駝峰命名開關,就會無法找到對應setter方法,導致屬性無法賦值成功。

解決辦法

方法一:手動添加setter方法

    private void setPassword(String pass_word) {
        this.pass_word = pass_word;
    }

方法二:若使用Lombok,規(guī)范屬性命名(可以保留命名不規(guī)范的屬性,避免影響項目原功能),本質與方法一相同

private String password;

方法三:在配置文件中關閉駝峰自動映射

mybatis-plus.configuration.map-underscore-to-camel-case=false

方法四:自定義Mapper方法,不使用實體類作為resultType,在xml中使用自定義resultMap,指定查詢結果字段與實體類屬性對應關系(沒有使用resultType,@TableField注解不會生效)

    <!--property="pass_word"是實體類屬性名,最終執(zhí)行的setter方法是setPass_word-->
    <!--column="pwd"是查詢結果字段名-->
    <resultMap id="myResultMap" type="com.example.demo.generator.domain.Camel">
        <result property="pass_word" column="pwd"/>
        <result property="age" column="age"/>
    </resultMap>
    <select id="myList" resultMap="myResultMap">
        select pwd, age from camel
    </select>  

參考

https://blog.csdn.net/HongYu012/article/details/123301153

到此這篇關于MybatisPlus查詢結果映射失敗@TableField失效解決辦法【源碼解析】的文章就介紹到這了,更多相關mybatisplus @tablefield失效內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java關鍵字this(動力節(jié)點Java學院整理)

    Java關鍵字this(動力節(jié)點Java學院整理)

    java中的this隨處可見,用法也多。通常情況下理解this關鍵字還是很容易的,但是在我初學的時候,有一個疑問卻一直不能很清晰的理解,現(xiàn)在慢慢的理解了,下面通過本文給大家記錄下,有需要的朋友參考下
    2017-03-03
  • 親測SpringBoot參數(shù)傳遞及@RequestBody注解---踩過的坑及解決

    親測SpringBoot參數(shù)傳遞及@RequestBody注解---踩過的坑及解決

    這篇文章主要介紹了親測SpringBoot參數(shù)傳遞及@RequestBody注解---踩過的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • RocketMQ中死信隊列問題排查與實戰(zhàn)解決

    RocketMQ中死信隊列問題排查與實戰(zhàn)解決

    隨著消息中間件在微服務架構中的普及,RocketMQ死信隊列作為保證消息可靠性的最后防線,非常重要,本文我們就來探討一下如何快速排查并解決RocketMQ死信隊列相關問題吧
    2025-07-07
  • Java實現(xiàn)訂單未支付則自動取消的五種方案及對比分析

    Java實現(xiàn)訂單未支付則自動取消的五種方案及對比分析

    作為電商系統(tǒng)中的核心功能,"訂單超時未支付自動取消" 是一個典型的定時任務場景,這個看似簡單的需求背后,隱藏著高并發(fā)、數(shù)據(jù)一致性、性能損耗等多個技術痛點,本文將從業(yè)務場景出發(fā),分析該需求的難點,然后依次介紹五種 Java 技術實現(xiàn)方案,需要的朋友可以參考下
    2025-05-05
  • 解決springboot啟動報錯bean找不到的問題

    解決springboot啟動報錯bean找不到的問題

    這篇文章主要介紹了解決springboot啟動報錯bean找不到原因,本文給大家分享完美解決方案,通過圖文相結合給大家介紹的非常詳細,需要的朋友可以參考下
    2023-03-03
  • java容器類知識點詳細總結

    java容器類知識點詳細總結

    這篇文章主要介紹了java容器類知識點詳細總結,
    2019-06-06
  • Java JDBC導致的反序列化攻擊原理解析

    Java JDBC導致的反序列化攻擊原理解析

    這篇文章主要介紹了Java JDBC導致的反序列化攻擊原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • Java?list移除元素相關操作指南

    Java?list移除元素相關操作指南

    這篇文章主要給大家介紹了關于Java?list移除元素相關操作的相關資料,文中介紹的方法包括增強for循環(huán)、迭代器、Stream流和removeIf()方法,同時還介紹了如何從一個列表中刪除包含另一個列表元素的方法,以及如何刪除指定下標位置的元素,需要的朋友可以參考下
    2024-12-12
  • 解決Eclipse中java文件的圖標變成空心J的問題

    解決Eclipse中java文件的圖標變成空心J的問題

    這篇文章主要介紹了解決Eclipse中java文件的圖標變成空心J的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • 查看jdk(java開發(fā)工具包)安裝路徑的兩種方法

    查看jdk(java開發(fā)工具包)安裝路徑的兩種方法

    若已經(jīng)安裝好了jdk(java開發(fā)工具包),也配置了環(huán)境變量,事后卻忘了安裝路徑在哪,如何查看jdk安裝路徑?本文給大家介紹了兩種查看jdk(java開發(fā)工具包)安裝路徑的方法,需要的朋友可以參考下
    2023-12-12

最新評論