Result Map深入理解映射(一对多,多对一)

Result Map的复杂使用

ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。

那么什么是一种描述呢?

在这里插入图片描述

这里有两张表,其中一张是学生,另一张是老师,那么这里的关系就是:

站在学生角度上:多个学生对应一个老师多对一

站在老师角度上:一个老师对应多个学生一对多

多对一深入理解1:

在这里插入图片描述

首先我们先分析一下实体类,

在这里插入图片描述

通过实体类,我们可以确定我们查询的目标其实就是 id,name ,teacher三样东西,

但是我们再来分析数据库中的表,我们发现,数据库中,关于student这张表,其实只有id,name,tid

这三个字段,那么但我使用:

<select id="getStudent" resultMap="StudentTeacher">
    select * from student
</select>

这句话的,我的返回的结果其实就是id,name,tid,对应数据库中的三个字段

那么问题来了teacher没了,因为

tid != teacher

这就是典型的查询时数据库字段名和实体类属性名不一致的问题

既然如此,那么我们就可以利用ResultMap来解决!

为啥呢? 还记得一开始其实就说过的ResultMap的思想就是来映射数据库字段和实体类属性名的,之前我们可以简单的利用这个功能来简单的做到类似于别名的功能,这里的情况无非就是复杂了一点,变成了一个对象而已。

好了,那么我们开始写ResultMap的映射:

<resultMap id="StudentTeacher" type="Student">
        <association property="teacher" column="tid"
                     javaType="Teacher" select="getTeacher"/>
</resultMap>

类似于别名操作,这里也是一个数据库字段名对应一个实体类属性名

property:实体类属性名

column:数据库字段名

当然由于teacher是一个对象,我们不能简单的做到直接映射,这里的javaType其实就是指定这个Teacher对象的对应的实体类

好了,下一步怎么办的呢?这个时候我们就会在想我们想要查询的时teacher这个对象,但是teacher这个对象其实存在于数据库中teacher这个表中,因此顺理成章,我们需要调用teacher这张表的查询语句,也就是

最后一个属性 :select=“getTeacher”

这个属性当然不是凭空产生的,我们是调用了另一个select语句

<select id="getTeacher" resultType="teacher">
     select * from teacher where id = #{id}
</select>

我们通过调用这个语句,来获得我们所需要的teacher对象,那么我们传入的条件是什么呢?

其实就是tid ,但是由于传入的只是一个属性,where id = #{id}中id不管写啥都是对,这个是Mybatis的一个特性

写道这里,相比你也明白了,这里的逻辑就类似SQL中子查询

话说回来,我们再来想一个问题,我们为啥要写这么复杂的查询的语句呢?其实仔细想想,我们在设计数据库考虑到数据库设计的三大范式,我们经常需要的数据分布在多个表中,并通过一定的连接点进行连接,这当然是好的,但是当我们在设计实体类时,就不能这样了,我们需要获得时对应的信息(teacher)而不是一个连接点(tid)

这时候我们就需要ResultMap来进行一一映射,来保证我们的查询结果

多对一深入理解2:

你以为到这里就结束了吗?

对于多对一查询,我们还有另一种方法

在这里插入图片描述

同样我们先来看select语句

select s.id sid, s.name sname, t.name tname
from student s,teacher t
where s.tid = t.id

和刚才的那么sql语句不同,这里使用了联表查询,由于使用别名操作,我们的结果也不同,

有sid,sname,tname;

不信?我们查查数据库
在这里插入图片描述

同样这三个字段名和我们实体类的属性名不同,那么这里就很顺理成章的要使用ResultMap来进行映射了

<resultMap id="StudentTeacher" type="Student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>

    <association property="teacher" javaType="Teacher">
        <result property="name" column="tname"/>
    </association>
</resultMap>

id——》sid

name——》sname

这两个都简单,不需要说明了,就是简单的映射

那么

teacher——》?

teacher 是一个复杂对象,我们要拆开再映射,我们把teacher拆开有个name(只需要name一个属性哦!)

name——》tname

至此为止,所有的属性都对应上了,那么映射也就完成了

综上所述:上述两个方法,各有优势,一个sql好写,一个xml好写,各取所需

还是那句话 :方法本身不重要,重要的是理解

我觉得只要有个映射的思想,慢慢的写,我们都能写出来

一对多深入理解1:

你又以为结束了?

我还没讲一对多呢!

这次我们站在老师角度,我们想要查询一个老师下所有的学生

其实思路是类似的,这次我们先不看代码,先分析。

我们的目标是:name List students

同样我们先使用第一种方法:

我们能查到啥:id name

没错这次我们从老师角度出发查询只能查到id和name

那么List students !=id

莫得,于是我们要进行映射!来上代码!

在这里插入图片描述

这里我们只要分析collection里的东西,colletion叫住集合,是用来映射一个集合对象。

同样:property:实体类属性名 javaType:该属性的类名 ofType :该集合的泛型

​ colume:id

同样类似于一对多,我们利用一个select语句 ,用id作为条件,来获取我们的所需要的集合对象

很简单,有木有!

一对多深入理解2:

来来来,最后一个了

看到这里,这个映射的概念想必以及十分的熟悉了

第二种一对多的方法:写好复杂的联表查询的SQL,然后一一映射,这里我就不做赘述了

直接上代码

<select id="getTeacher" resultMap="TeacherStudent">
    select s.id sid, s.name sname , t.name tname, t.id tid
    from student s,teacher t
    where s.tid = t.id and t.id=#{id}
</select>

<resultMap id="TeacherStudent" type="Teacher">
    <result  property="name" column="tname"/>
    <collection property="students" ofType="Student">
        <result property="id" column="sid" />
        <result property="name" column="sname" />
        <result property="tid" column="tid" />
    </collection>
</resultMap>

我们首先在SQL语句中,查出了啥?

sid

sname

tname

tid

那么我们来一一对应

name ——》tname

Liststudents ——》 ?

这里同样我们再拆,一个student拆成 id name tid三个东西再来一一对应

id——》sid

name——》sname

tid——》tid

这里在注意一点,这里我们只需要写ofType=“student”

好了,完成收工,2个小时2000字左右,望各位学有所成

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值