resultMap避坑指南

1,427 阅读4分钟

一.初识ResultMap

ResultMap:mybatis中一种用来在mapper.xml文件中处理结果集映射的标签。它的出现有效的解决了resultType仅能处理字段名与pojo属性名一致的局限。

若字段名和pojo的属性名不一致,则可以通过resultMap设置自定义映射。同时resultMap的使用可实现延迟加载,实现sql语句执行效率增加。

二.resultMap处理字段和属性的映射关系

       属性:
         id:设置自定义映射的唯一标识()
         type:查询数据要映射的实体类型
         
       子标签:
         result设置普通类型的映射关系
         id设置主键的映射关系(这里的id是一个标签属性)
         association:设置多对一的映射关系 
         collection:设置一对多的映射关系
         
       子标签属性:
           property:设置映射关系中实体类中的属性名 
           column:设置映射关系中表中的字段名
           

Snipaste_2022-05-02_13-28-56.png

若字段名和实体类中的属性名不一致,也可以使用驼峰进行解决,但前提pojo属性是满足java的命名规制,以及数据库命名规范

例如:字段名 user_id , 属性名得是userId 才能符合驼峰的使用规则,也就是属性名要定义为将字段名中“”去掉,同时紧接 “”的第二个单词的首字母大写

将表中字段的下划线自动转换为驼峰

setting name="mapUnderscoreToCamelCase" value="true"/>

也可以通过为字段起别名的方式,保证和实体类中的属性名保持一致

三:多对一映射级联

任务:查询员工信息以及员工所对应的部门信息

方法一:优点:简单,缺点:代码冗余,灵活性差

image.png

方法二:较以上方法可观性强

association处理多对一映射处理,association标签里的为“一”,外面的为多。多个员工对应一个部门,所以association标签就对应部门。

Snipaste_2022-05-02_14-08-48.png

association使用注意事项:

1.association(级联)标签首先要是放在resultMao标签体内部的

2.association标签里的javaType属性(改属性的类型)不能遗漏,不然mybatis不知道是哪个实体类的属性和实体类表相对应

方法三:分布查询 优点:灵活性强,效率高 缺点:较复杂

分布查询本质上是将上述sql语句一分为二的,去分别查询。在查询员工信息以及员工所对应的部门信息的任务中先查询到员工的部门id再通过这个id去找对应在部门表中的id从而找到部门信息。

这里分二步完成

第一步:在员工mapper接口中定义查询员工id的方法,自定义resultMap,写selectsql语句

Snipaste_2022-05-02_14-19-23.png

首先这里的column是将sql以及查询结果中的某个字段设置为分步查询的条件,意思就是将在员工表中查到的部门id的这个字段名称以及值作为查询部门id的条件。注意:这个部门表id的字段名要和员工表中部门id字段名要一致, 或者查询时设置别名。

select”:设置分布查询,查询某个属性中的值的sql标识,简单讲就是用这个以这个select去调用部门mapper接口里的方法。这里的select的值是要查询的表对应的pojo类的全类名加上.方法名---- 【com.atguigu.MyBatis.mapper.DeptMapper】全类名+【getEmpDeptByStep】方法名

第二部在部门mapper接口中定义查询员工id的方法,自定义resultMap,写selectsql语句查询部门的信息

Snipaste_2022-05-02_14-27-38.png

四:一对多映射处理

collection处理一对多映射处理,这和association的使用方法大同小异。唯一不同的是collecion标签中是oftype属性。

类型区别
javaTypeJavaType是用来指定pojo中属性的类型private User user
ofType指定的是映射到list集合属性中pojo的类型 private List 《User》

Snipaste_2022-05-02_14-36-21.png

一对多分布查询

Snipaste_2022-05-02_14-36-59.png

五.延迟处理

分布查询有个优点可以实现延迟加载,它可提高查询效率

首先要在必须在核心配置文件中设置全局配置信息

<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>

lazyLoadingEnabled:延迟加载的全局开关,当开启时,所有关联对象都会延迟加载 aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则每个属性会按需加载(默认是false,我们不用设置) 此时可通过association和 collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType="lazy(延迟加载)|eager(立即加载)"

实现延迟加载后,可按需加载,获取的数据是什么,就会执行相应的sql。

Snipaste_2022-05-02_14-43-36.png 这是个分布查询,我设置了Customer和CustomerType两张表和对应的属性,接下来调用方法

image.png

Snipaste_2022-05-02_14-46-21.png

可见日志打印了出执行了两个sql语句

接下来实现单独获取Customer里的属性值

Snipaste_2022-05-02_14-47-44.png

image.png 可见只执行了一条sql语句

综上所述:设置延迟加载能提高效率,避免不必要的sql语句执行,按需加载