MyBatis03:嵌套查询、嵌套结果、延迟加载

MyBatis03:嵌套查询、嵌套结果、延迟加载,第1张

文章目录
  • 前言
  • 一、ResultMap
    • 1. 查询语句的执行过程
    • 2. ResultMap的优势
    • 3. ResultMap的作用
    • 4. 数据类型
  • 二、一对一,对象属性
    • 1. 一对一,嵌套查询
    • 2. 一对一,嵌套结果
  • 三、一对多,集合属性
    • 1. 一对多,嵌套查询
    • 2. 一对多,嵌套结果
  • 四、嵌套查询和嵌套结果的联系和区别
    • 1. 嵌套结果
    • 2. 嵌套查询
  • 五、 延迟加载/懒加载
    • 1. 作用
    • 2. 如何配置懒加载
    • 3. 案例说明
  • 总结


前言

这篇文章是对查询结果ResultMap的进一学习。前面一篇文章的末尾,简单的介绍了resultType和resultMap的联系与区别。


一、ResultMap 1. 查询语句的执行过程

sql语句查询到结果后,将结果返回给resultMap,由resultMap创建对象。根据column和property的映射关系,获取数据库里字段的值,并将其赋给Java的属性。

2. ResultMap的优势

事实上对于一个复杂的交互代码,可能需要写上千行的代码来实现连接映射(join mapping)使用ResultMap的目的就是让我们只需要使用简单的配置语句,而不需要详细地处理结果映射。对更复杂的语句除了使用一些必须的语句描述外,就不需要做其他的处理了。

3. ResultMap的作用

将查询结果映射为对象,再把对象映射到集合里(因为不知道会查询到多少对象,所以需要将对象映射到集合里)。我们只需要对应好字段和属性即可。通过ResultMap建立数据库字段和Java属性的映射关系。

4. 数据类型
  1. javaType:实体属性的数据类型,可以省略
  2. jdbcType:数据库字段的数据类型,可以省略

通过mybatis框架的转化器,可以将数据库里的类型转化为Java程序类型

二、一对一,对象属性

背景:为学生的班级对象属性映射值

<sql id="base_info">id,name,sex,birthday,age,classidsql>
<select id="selectByPrimaryKey" resultMap="baseMap">
    select <include refid="base_info">include> from student
    where id = #{id}
select>

一对一的查询语句就是通过某个参数,查询到某个对象

1. 一对一,嵌套查询

根据查询条件column,通过select查询语句将查询到的结果映射给property属性

<association property="clazz" column="classid" select="com.dao.ClazzMapper.selectByPrimaryKey">association>
标签/属性属性值含义/作用
association标签为对象属性映射值
propertyclazz对象属性
columnclassid作为查询条件的数据库字段
selectcom.dao.ClazzMapper.selectByPrimaryKey调用方法进行查询
2. 一对一,嵌套结果

分别建立对象属性和对象属性的属性的映射关系即可

<association property="clazz" javaType="com.bean.Clazz">
    
    <id column="classid" property="id">id>
    <result column="classname" property="classname">result>
association>
标签/属性属性值含义/作用
association标签为对象属性映射值
propertyclazz对象属性
javaTypecom.bean.Clazz对象属性的数据类型
id标签用来设置主键
result标签用来设置其他字段
columnclassid数据库的字段
propertyid对象属性的属性
三、一对多,集合属性

背景:为学生的成绩集合属性映射值

<select id="selectAll" resultMap="baseMap2">
    select s.*, c.classname,sc.id scid, sc.score, sc.course, sc.examdate  from student s left join clazz c on s.classid = c.id
                                                                            LEFT JOIN scores sc ON s.id = sc.stuid
select>

一对多的查询用到了多表联查,查询到的是多条数据。

1. 一对多,嵌套查询

根据查询条件column,通过select查询语句将查询到的结果映射给property属性

<collection property="scores" column="id" select="com.dao.ScoresMapper.selectByStuid">collection>
标签/属性属性值含义/作用
collection标签为集合属性映射值
propertyscores集合属性
columnid作为查询条件的数据库字段
selectcom.dao.ScoresMapper.selectByStuid调用方法进行查询
2. 一对多,嵌套结果

分别建立对象属性和对象属性的属性的映射关系即可
注意:当字段名冲突时,需要起别名

<collection property="scores" ofType="com.bean.Scores">
    <id column="scid" property="id">id>
    <result column="score" property="score">result>
    <result column="course" property="course">result>
    <result column="examdate" property="examdate">result>
collection>
标签/属性属性值含义/作用
collection标签为集合属性映射
propertyscores指代集合属性
ofTypecom.bean.Scores集合属性的数据类型
id标签用来设置主键
result标签用来设置其他子段
columnscid数据库字段
propertyid集合属性的属性
四、嵌套查询和嵌套结果的联系和区别 1. 嵌套结果

嵌套结果是嵌套查询结果。

 <resultMap id="baseMap" type="com.bean.Pet">
        <id property="petId" column="petId">id>
        <result property="petName" column="petName">result>
        <result property="birthday" column="birthday">result>
        <result property="typeId" column="typeId">result>
        
        <association property="pettype" javaType="com.bean.Pettype">
            <id property="typeId" column="typeId">id>
            <result property="typeName" column="typeName">result>
        association>
        
        <collection property="healhistorys" ofType="com.bean.Healhistory">
            <id property="id" column="id">id>
            <result property="petId" column="petId">result>
            <result property="health" column="health">result>
            <result property="checkdate" column="checkdate">result>
        collection>
    resultMap>
<select id="selectByPrimaryKey" resultMap="baseMap">
        select p.*, pt.*, h.id,h.petId hpetId, h.health, h.checkdate from pet p
            left join pettype pt on p.typeId = pt.typeId
            left join healhistory h on p.petId = h.petId
            where p.petId = #{petId}
select>

嵌套结果使用的是多表联查,所有字段都需要查出来,然后根据映射关系一一进行映射。需要注意,当列名相同时,需要起别名来防止字段冲突。

2. 嵌套查询

嵌套查询是嵌套查询语句。

<resultMap id="baseMap2" type="com.bean.Pet">
        <id property="petId" column="petId">id>
        <result property="petName" column="petName">result>
        <result property="birthday" column="birthday">result>
        <result property="typeId" column="typeId">result>
        <association property="pettype" column="typeId" select="com.dao.PettypeMapper.selectByPrimaryKey">association>
        <collection property="healhistorys" column="petId" select="com.dao.HealhistoryMapper.selectByPetid">collection>
resultMap>
<select id="selectAll" resultMap="baseMap2">
    select * from pet
select>

嵌套查询使用的是单表查询,对象属性和集合属性通过调用自己的映射的查询方法来获取的。
优点:查询语句简单,与相关子查询相似,但比相关子查询效率高,因为带缓存。

五、 延迟加载/懒加载

作用于嵌套查询

1. 作用

有时候我们在查询数据时,要查询的数据不需要包含对象属性或集合属性时,我们该怎么查询?我们可以单独设置一个返回值类型,在获取返回值的时候不添加对象属性或集合属性,这样就不会获取到对象属性和集合属性了。但如果我们不单独添加这样一个返回值类型,而是在原有的返回值类型包含对象属性和集合属性的情况下,如何实现可以在不查询对象属性和集合属性的时候不加载对象属性和集合属性,只有在查询对象属性和集合属性的时候才加载对象属性和集合属性。如果使用的是嵌套查询,这时就可以使用延迟加载。在设置延迟加载/懒加载后,可以极大的提高查询效率。在不需要查询对象属性和集合属性的时候,程序就不会执行对象属性和集合属性相关的查询语句。只有在指定要查询的对象和集合后,才会查询对应的对象和属性。

2. 如何配置懒加载

在MyBatis的主配置文件中为ResultMap映射的对象属性和集合属性一起做配置,添加如下配置语句。

3. 案例说明
  1. 不添加延迟加载时,如果我们使用嵌套查询查询普通属性时,程序也会查询对象属性和集合属性,这样就会导致查询效率较低。

  2. 当我们添加延迟加载后,当我们只查询普通属性时,就不会查询成员属性和集合属性

  3. 添加延迟加载后,只有当我们查询成员属性和集合属性时,才会执行相应的查询语句


总结

今天,主要学了ResultMap如何为对象属性和集合属性设置返回值的映射。可以通过嵌套查询和嵌套结果两种方式来实现,这里分别介绍了嵌套查询和嵌套结果用到的标签和属性,主要是明确如何使用。最后还介绍了RresultMap的延迟加载,如何配置,以及延迟加载的优点。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/721921.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存