Mybaits源码赏析四:通过注解实现嵌套子查询


提示:以下是本篇文章正文内容,下面案例可供参考

一、语法实现

  @Select("SELECT * FROM " +
      "blog WHERE id = #{id}")
  @ConstructorArgs({
      @Arg(column = "id", javaType = int.class, id = true),
      @Arg(column = "title", javaType = String.class),
      @Arg(column = "author_id", javaType = Author.class, select = "org.apache.ibatis.binding.BoundAuthorMapper.selectAuthor"),
      @Arg(column = "id", javaType = List.class, select = "selectPostsForBlog")
  })
  Blog selectBlogUsingConstructor(int id);

二、实现原理

在这里插入图片描述
一般一个注解只能在一个地方,加了这个注解,表明了可以@Arg,可以在@ConstructArgs里使用多次。那么,此注解究竟是怎么实现了嵌套的查询,很好奇,下面我将通过源码一步一步揭开Mybaits内部的神秘面纱…

2.1 @Arg里面的column值代表了什么?

在这里插入图片描述
返回值Blog对象,有四个属性并没有跟我们的注解@Arg里面的column属性对应,有没有一种可能是在代码里进行了转换?
在这里插入图片描述
调用的过程是这样的,首先通过代理技术创建了mapper的代理对象,因为返回的是一个对象所以调用的是selectOne的方法,selelctOne调用的又是selectList的方法,通过statement,查询到了MappedStatement对象,我们看MappedStatement通过解析xml标签,mapper接口上面的注解给我们构造了怎样的映射对象,在ResultMaps里面我们看到ResultMapping对象里的property属性依然为空,所以我们可以推断并没有在构建configuration对象的时候将在@Arg里面的column属性进行映射成我们的要返回对象的属性。接着往下看…
在这里插入图片描述
接着就是利用excutor开始一大堆的查询,先判断是否开启了二级缓存,开启了二级缓存的话先去查询二级缓存,然后没有开启的话就去调用queryFromDataBase()方法,注意这个方法名虽然从表面上看是从数据库查询,其实也是先查询的一级缓存没有的话然后再去查数据库,利用statement对象去执行解析好的SQL,实际就是调用的JDBC的接口,然后对返回的数据进行处理,下面我们来到了对行数据的处理方法中…
在这里插入图片描述
请注意,这个方法已经返回了我们想要的对象,哪几个属性都赋值了,但是我们还有搞清楚到底column对象是怎么跟Blog对象的属性进行对应的,下面我们到这个方法里面查看
在这里插入图片描述
创建参数化返回的对象,这里的author_id不就是我们在@Arg注解里面定义的colun参数的值吗,然后判断这个嵌套查询的id不为null就开启了嵌套子查询
等等… 这个嵌套查询的id是什么鬼?我们打着打破沙岗问到底,问问公鸡几条腿的精神,继续探索…
在这里插入图片描述

原来是在这里构建ResultMapping对象的时候利用构建者模式构建的,那么为啥有的为null而就知道author_id有值了呢?
继续往下看…
在这里插入图片描述
这里传了这么一个参数,这个参数哪里来的呢?
在这里插入图片描述
原来就是我们@Arg注解里面的select属性,真相大白…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值