MyBatis中的resultMap

场景

查询论坛项目首页的帖子列表

  1. 首先需要从MySQL数据库中多表查询到 帖子信息 和 作者信息,并得到一个 List,为了更规范我定义了一个对象 DiscussPostDTO 来定义每一项
  2. 但是这样还不足够,每一个帖子还有额外的 点赞数量,它存在 Redis 中
  3. 以及我需要列表分页,使用了 PageHelper 插件,它的分页封装对象 PageInfo 的数据集属性类型是 List

问题

现在问题来了,我应该返回给前端一个怎样的对象?

更确切地说,DiscussPostDTO 的 List 封入 PageInfo 肯定是没有问题的,关键是 likeCount 怎么塞入返回对象中?

解决方案

likeCount 肯定是每一项不同的,所以它应该被放在 DiscussPostDTO 一级,那么我返回的仍然是 PageInfo 对象确定了

为了更清楚地说明问题所在,我来描述一下被 pass 掉的方案

  • 直接定义对象(不带likeCount属性)+ MyBatis SQL 语句直接返回 DiscussPostDTO 对象类型
    pass,因为对象被写死了,likeCount 没法塞入对象中
    那么加一个属性呢?还是直接用 resultType 的话会报字段不匹配
    那么套一层 List<Map<Stirng,Object>> 呢?
    可以是可以,太不好看,代码写出来太丑,而且返回结构也不好看,likeCount 独立于对象之外
  • MyBatis返回 map ,再往里面加一项
    也可以,但还是不好看,以及每一项的结构语义不清晰,我还是希望能定义一个对象

resultMap

于是我想起来了resultType,之前是用来解决嵌套对象的问题的:一个对象属性是另一个对象的引用
像这样:

    <resultMap id="course_coach2" type="com.fitness.entity.CourseInfo">
        <id property="courseId" column="course_id"/>
        <result property="courseName" column="course_name"/>
        <result property="description" column="description"/>
        <result property="startTime" column="start_time"/>
        <result property="frequency" column="frequency"/>
        <result property="price" column="price"/>
        <result property="capacity" column="capacity"/>
        <association property="courseCoach" javaType="CourseCoach">
            <association property="coach" javaType="Coach">
<!--                <id property="coachId" column="coach_id"/>-->
                <result property="coachName" column="coach_name"/>
            </association>
        </association>
    </resultMap>

    <select id="getAllCourseInfo" resultMap="course_coach2">
        SELECT course_info.course_id, course_name,
               description,
               start_time,
               frequency,
               price,
               capacity,
               a.coach_name
        FROM course_info
                 LEFT JOIN
             (SELECT coach.coach_id, coach_name, course_coach.course_id
              FROM coach,
                   course_coach
              where course_coach.coach_id = coach.coach_id) a
             ON course_info.course_id = a.course_id
    </select>

其实刚刚这里,问题的答案就呼之欲出了

那么加一个属性呢?还是直接用 resultType 的话会报字段不匹配

用 resultMap 手动指定每个字段的匹配关系,单独留一个 likeCount 属性空着,就不会存在字段不匹配的问题
同时后面将 likeCount 封入对象时可以直接调用set方法,方便、优雅

    <resultMap id="DiscussPostDTO" type="DiscussPostVO">
        <id property="id" column="id"/>
        <result property="userId" column="user_id"/>
        <result property="username" column="username"/>
        <result property="headerUrl" column="header_url"/>
        <result property="title" column="title"/>
        <result property="content" column="content"/>
        <result property="type" column="type"/>
        <result property="status" column="status"/>
        <result property="createTime" column="create_time"/>
        <result property="commentCount" column="comment_count"/>
        <result property="score" column="score"/>
    </resultMap>
            for(DiscussPostVO discussPostVO :pageInfo.getList()){
                long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, discussPostVO.getId());
                discussPostVO.setLikeCount(likeCount);
            }
posted @ 2023-02-16 02:22  YaosGHC  阅读(28)  评论(0编辑  收藏  举报