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!!!
奥里给。

原文地址:https://www.cnblogs.com/Fzeng/p/14766671.html