Mybatis多表查詢出現null字段


寫在前面

今天使用mybatis實現多表查詢,記錄一下其中遇到的坑

mybatis多表查詢簡介

mybatis多表查詢主要有兩個方式,通俗易懂的來說就是一個是查詢少量屬性(association),一個是把多個結果封裝成list(collection),我現在對mybatis的理解害不是很深入,用大白話的方法給大家分享一下我的理解。

association用法

association用法很簡單,我貼一段代碼

<mapper namespace="com.example.springbootvue.mapper.UserMapper">
    <resultMap id="UserMap" type="com.example.springbootvue.entity.User">
        <id column="user_id" jdbcType="INTEGER" property="userId"/>
        <result column="username" jdbcType="VARCHAR" property="username"/>
        <result column="role_id" jdbcType="INTEGER" property="roleId"/>
        <association property="roleName" column="role_id"
                     select="com.example.springbootvue.mapper.UserMapper.getRoleName">
        </association>

    <select id="getRoleName" resultType="java.lang.String" parameterType="integer">
        select role_name
        from sp_role
        where role_id = #{value}
    </select>

這個resultMap被我簡化過,方便大家觀看,這里resultMap指向的是我的User類,我在User類中定義了roleId,這是Role類中的主鍵,這個實例的目的主要是查詢用戶和用戶的角色
在association中,roleName是User類中的外鍵,colum是傳入getRoleName方法中的參數,沒有仔細查詢資料,感覺association像回調函數,先找到User,再通過User中的role_id去Role表中查詢role_name,事實上好像也真是這樣,我debug中mybatis確實像數據庫發起了兩次請求

2021-05-13 23:22:30.499  INFO 4576 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2021-05-13 23:22:31.305  INFO 4576 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2021-05-13 23:22:31.315 DEBUG 4576 --- [           main] c.e.s.m.UserMapper.selectByPrimaryKey    : ==>  Preparing: select user_id , username, qq_open_id, `password`, user_email, user_email_code, is_active, user_sex, user_qq, user_tel, user_xueli, user_hobby, user_introduce, create_time, update_time,role_id from sp_user where user_id = ? 
2021-05-13 23:22:31.345 DEBUG 4576 --- [           main] c.e.s.m.UserMapper.selectByPrimaryKey    : ==> Parameters: 1(Integer)
2021-05-13 23:22:31.372 DEBUG 4576 --- [           main] c.e.s.mapper.UserMapper.getRoleName      : ====>  Preparing: select role_name from sp_role where role_id = ? 
2021-05-13 23:22:31.373 DEBUG 4576 --- [           main] c.e.s.mapper.UserMapper.getRoleName      : ====> Parameters: 31(Integer)
2021-05-13 23:22:31.375 DEBUG 4576 --- [           main] c.e.s.mapper.UserMapper.getRoleName      : <====      Total: 1
2021-05-13 23:22:31.379 DEBUG 4576 --- [           main] c.e.s.m.UserMapper.selectByPrimaryKey    : <==      Total: 1

實錘!!

查詢字段有null的解決方案

如果查詢出來有字段是null,檢查一下sql標簽中的colum

    <sql id="Base_Column_List">
        user_id
        , username, qq_open_id, `password`, user_email, user_email_code, is_active,
    user_sex, user_qq, user_tel, user_xueli, user_hobby, user_introduce, create_time, 
    update_time,role_id
    </sql>

這個xml是我用mybatis-generate生成的,檢查一下里面的字段是否都對應了數據庫中的colum,我之前roleName一直查詢不出來,就是因為我漏掉的role_id,導致我查詢出來的user中role_id是null,

在association中的select中的方法

select中的方法最好是加上路徑(com.xxx.xxx.xxx.xxxMapper.xxx),檢查方法中的形參是否正確(反正我在這里給自己挖坑了,大家這么聰明應該不會在這里掉下去)

collection

colletion是我實現多級菜單查詢用到的,還是先上代碼

    <resultMap id="menuMap" type="com.example.springbootvue.entity.Menu">
        <id column="ps_id" jdbcType="SMALLINT" property="psId"/>
        <result column="ps_name" jdbcType="VARCHAR" property="psName"/>
        <result column="ps_pid" jdbcType="SMALLINT" property="psPid"/>
        <collection property="children" ofType="com.example.springbootvue.entity.Menu"
                    column="ps_id" select="findMenuByParentId"/>
    </resultMap>

我在Menu類中定義了一個列表List<Menu> children,所以colection property=‘children’(colection集合嘛,肯定是list類型)
ofType指向Menu這個類(畢竟children是Menu的屬性嘛),同樣的 column可以理解為是后面select=‘findMenuByParentId’的參數
然后不管是菜單有多少級,它都可以給你全部嵌套進去(經典套娃)
缺點就是一次只能查詢一個一級菜單(我的一級菜單有五個,只能分五次查詢來解決了,大佬有好的建議還請指教)

我是末尾

希望大家的代碼永無bug!!!
奧里給。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM