关于集合的扩展:集合的嵌套结果映射

关于集合的扩展:集合的嵌套结果映射

问题描述:

课程里面教了集合的嵌套Select查询,之后在括展知识的时候在MyBatis官方文档看到了另一种方式也就是集合的嵌套结果映射。https://mybatis.org/mybatis-3/zh/sqlmap-xml.html

文档的举例是一个Blog博客中可以有多个Post文章。

<resultMap id="blogResult" type="Blog">
  <id property="id" column="blog_id" />
  <result property="title" column="blog_title"/>
  <collection property="posts" ofType="Post">
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    <result property="body" column="post_body"/>
  </collection>
</resultMap>
<select id="selectBlog" resultMap="blogResult">
  select
  B.id as blog_id,
  B.title as blog_title,
  B.author_id as blog_author_id,
  P.id as post_id,
  P.subject as post_subject,
  P.body as post_body,
  from Blog B
  left outer join Post P on B.id = P.blog_id
  where B.id = #{id}
</select>

那么我也想在对课程中的Goods和GoodsDetail使用这样的方法,可以得到集合的size可是返回的结果都是null

https://img1.sycdn.imooc.com//climg/63abf574098233af05190646.jpg

尝试过的解决方式:

我将xml修改了为符合MyBatis官方文档的形式

    <resultMap id="rmGoods1" type="com.imooc.mybatis.entity.Goods">
        <id column="goods_id" property="goodsId"></id>
        <collection property="goodsDetails" ofType="com.imooc.mybatis.entity.GoodsDetail">
            <id property="gdId" column="gd_id"></id>
            <result property="goodsId" column="goods_id"></result>
            <result property="gdPicUrl" column="gd_pic_url"/>
            <result property="gdOrder" column="gd_order"/>
        </collection>
    </resultMap>
    <select id="selectOneToMany" resultMap="rmGoods1">
            select g.* from t_goods g join t_goods_detail gd 
            on g.goods_id = gd.goods_id 
            where g.goods_id = #{id}
    </select>

测试代码为:

@Test
public void testOneToMany() throws Exception {
    SqlSession session = null;
    try {
        session = MyBatisUtils.openSession();
        List<Goods> list = session.selectList("goods.selectOneToMany",760);
        for(Goods goods:list) {
            System.out.println(goods.getTitle() + ":" + goods.getGoodsDetails().size());
        }
    } catch (Exception e) {
        throw e;
    } finally {
        MyBatisUtils.closeSession(session);
    }
}

为什么这个官方文档的方法就不好使了呢...

(谢谢)

正在回答

登陆购买课程后可参与讨论,去登陆

1回答

同学你好,1、Goods属性值为null,是因同学没有映射,则建议同学进行映射。

2、GoodsDetail属性值为null,是因同学没有查询t_goods_detail表中的列,则建议在SQL语句中添加对应的列。修改后代码如下所示:

https://img1.sycdn.imooc.com//climg/63ac06da09e66fd907630369.jpg

<resultMap id="rmGoods" type="com.imooc.mybatis.entity.Goods">
    <!--    good映射    -->
    <id column="goods_id" property="goodsId"></id>
    <id column="title" property="title"></id>
    <!--    goodsDetails映射    -->
    <collection property="goodsDetails" ofType="com.imooc.mybatis.entity.GoodsDetail">
        <id property="gdId" column="gd_id"></id>
        <result property="goodsId" column="goods_id"></result>
        <result property="gdPicUrl" column="gd_pic_url"/>
        <result property="gdOrder" column="gd_order"/>
    </collection>
</resultMap>
<select id="selectOneToMany" resultMap="rmGoods2">
        select g.*,gd.* from t_goods g join t_goods_detail gd
        on g.goods_id = gd.goods_id
        where g.goods_id = #{id}
</select>

祝学习愉快!

  • 只能卷了 提问者 #1

    谢谢老师。

    我本来一位MyBatis还是会像之前学习过的那些例子,会自己去找映射的属性和字段,因为不是以及设置了驼峰命名转换了嘛。所以我觉得这里也没必要添加详细的字段匹配了,之后一直没想通这里MyBatis怎么就不自己找映射关系了呢。


    现在自己的理解是,对于表连接的结果,MyBatis也无法把其当成单纯的Goods实体。所以在获得SQL查询结果后,需要告诉MyBatis属性与字段的对应关系,MyBatis才能把对应字段的值一个一个的赋值属性。总结一下就是,在返回表连接的结果时,必须详细指明每一个属性/字段的映射关系。

    不知理解是否正确?

    2022-12-30 18:26:34
  • 好帮手慕小蓝 回复 提问者 只能卷了 #2

    同学你好,同学的理解是正确的。

    祝学习愉快~

    2022-12-30 18:29:01
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师