• JavaEE--Mybatis学习笔记(五)--关联关系查询


    1.关联查询

      当查询内容涉及到具有关联关系的多个表时,就需要使用关联查询。根据表与表间的关联关系的不同,关联查询分为四种:

      (1)一对一关联查询

      (2)一对多关联查询

      (3)多对一关联查询

      (4)自关联

      (5)多对多关联查询

      由于日常工作中最常见的关联关系是一对多、多对一与多对多,所以这里就不专门只讲解一对一关联查询了,其解决方案与多对一解决方案是相同的。

    • 一对多关联查询

        这里的一对多关联查询是指,在查询一方对象的时候,同时将其所关联的多方对象也都查询出来

        下面是国家Country 与 部长Minister间的一对多关系进行演示.

      • 建表

      country表

      minister表

    • 实体

    • 一对多通过多表连接查询实现
    <mapper namespace="com.ryanxu.dao.ICountryDao">
        <resultMap type="Country" id="countryMapper">
            <id column="cid" property="cid" />
            <result column="cname" property="cname" />
            <collection property="ministers" ofType="Minister">
                <id column="mid" property="mid" />
                <result column="mname" property="mname" />
            </collection>
        </resultMap>
        
        <select id="selectCountryById" resultMap="countryMapper">
            select cid,cname,mid,mname
            from country join minister on country.cid = minister.countryId
            where cid = #{id}
        </select>
    </mapper>
    注意 result里面 column和property之间要有空格 不然会报错
    Cause: org.xml.sax.SAXParseException: Element type "result" must be followed by either attribute specifications, ">" or "/>".
    
    因为是多表查询 返回的有minister的成员变量 若resultType使用的是Country 则没有mid和mname的get/set方法 所以使用resultMapper 将返回的包装成Country类 collection就是Set里面就是minister
    •  测试

      • 一对多通过多表单独查询实现
        <select id="selectMinisterByCountry" resultType="Minister">
            select mid,mname from minister where countryId = #{ryanxu}
        </select>
        
        <resultMap type="Country" id="countryMapper">
            <id column="cid" property="cid"/>
            <result column="cname" property="cname"/>
            <collection property="ministers"
                        ofType="Minister"
                        select="selectMinisterByCountry"
                        column="cid"/>
        </resultMap>
        <select id="selectCountryById" resultMap="countryMapper">
            select cid,cname from country where cid = #{cid}
        </select>
      •  测试

    • 多对一关联查询
        • 实体

      •  多对一通过多表连接查询实现
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper 
      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
      "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.ryanxu.dao.IMinisterDao">
        <resultMap type="Minister" id="MinisterMapper">
            <id column="mid" property="mid" />
            <result column="mname" property="mname" />
            <association property="country" javaType="Country">
                <id column="cid" property="cid" />
                <result column="cname" property="cname" />
            </association>
        </resultMap>
        <select id="selectMinisterById" resultMap="MinisterMapper">
            select mid,mname,cid,cname
            from minister join country on minister.countryId = cid
            where mid = #{mid}
        </select>
    </mapper>
    •  测试

    •  多对一通过多表单独查询方式实现
        <select id="selectCountryById" resultType="Country">
            select cid,cname from country where cid = #{cid}
        </select>
        <resultMap type="Minister" id="MinisterMapper">
            <id column="mid" property="mid"/>
            <result column="mname" property="mname"/>
            <association property="country"
                         javaType="Country"
                         select="selectCountryById"
                         column="countryId"/>
        </resultMap>
        <select id="selectMinisterById" resultMap="MinisterMapper">
            select mid,mname,countryId from minister where mid = #{mid}
        </select>
    • 测试

    • 自关联查询

        (1)自关联的DB表

     

        (2)以一对多方式处理

          (A)查询指定栏目的所有子孙栏目

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper 
      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
      "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      <mapper namespace="com.ryanxu.dao.INewsLableDao">
    <!--     <select id="selectChildrenByParent" resultMap="newslabelMapper">
              select id,name from newslabel where pid = #{pid}
          </select> -->
          <resultMap id ="newslabelMapper" type="NewsLabel">
              <id column="id" property="id"/>
              <result column="name" property="name"/>
              <collection property="children"
                          ofType="NewsLabel"
                          select="selectChildrenByParent"
                          column="id"/>
          </resultMap>
          <select id="selectChildrenByParent" resultMap="newslabelMapper">
              select id,name from newslabel where pid = #{pid}
          </select>
      </mapper>

          (B)查询指定栏目及其所有子孙栏目

          <select id="selectChildrenByParent" resultMap="newslabelMapper">
              select id,name from newslabel where pid=#{pid}
          </select>
          <resultMap id ="newslabelMapper" type="NewsLabel">
              <id column="id" property="id"/>
              <result column="name" property="name"/>
              <collection property="children"
                          ofType="NewsLabel"
                          select="selectChildrenByParent"
                          column="id"/>
          </resultMap>
          
          <select id="selectNewsLabelById" resultMap="newslabelMapper">
              select id,name from newslabel where id = #{id}
          </select>

     

        (3)以多对一方式处理(查询当前栏目和所有的父栏目)

     

          <resultMap id ="newslabelMapper" type="NewsLabel">
              <id column="id" property="id"/>
              <result column="name" property="name"/>
              <association property="parent"
                           javaType="NewsLabel"
                           select="selectNewsLabelById"
                           column="pid"/>
          </resultMap>
          
          <select id="selectNewsLabelById" resultMap="newslabelMapper">
              select id,name,pid from newslabel where id = #{id}
          </select>
    • 多对多关联查询
      • 实体类

     

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper 
      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
      "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.ryanxu.dao.IStudentDao">
        <resultMap id="studentMapper" type="Student">
            <id column="sid" property="sid" />
            <result column="sname" property="sname" />
            <collection property="cources" ofType="Course">
                <id column="cid" property="cid" />
                <result column="cname" property="cname" />
            </collection>
    
        </resultMap>
        <select id="selectStudentById" resultMap="studentMapper">
            select sid,sname,cid,cname
            from student join sc on student.sid = sc.studentId join course on
            sc.courseId = course.cid
            where sid = #{sid}
        </select>
    </mapper>

     2.关联查询

    • 概念:Mybatis中的延迟加载,也称为懒加载,是指在进行关联查询时,按照设置延迟规则推迟对关联对象的select查询。延迟加载可以有效地减少数据库压力。需要注意的是,Mybatis的延迟加载只是对关联对象的查询有延迟设置,对于主加载对象都是直接执行查询语句的。
    • 加载时机

        直接加载:执行完对主加载对象的select语句,马上执行对关联对象的select查询。

        侵入式延迟:执行对主加载对象的查询时,不会执行对关联的查询。但当要访问主加载对象的详情时,就会马上执行关联对象的select查询。即对关联对象的查询执行,侵入到了主加载对象的详情访问中。也可以这样理解:将关联对象的详情侵入到了主加载对象          的详情中,即将关联对象的详情作为主加载对象的详情的一部分出现了。

        深度延迟:执行对主加载对象的查询时,不会执行对关联对象的查询。访问主加载对象的详情时也不会执行关联对象的select查询。只有当真正访问关联对象的详情时,才会执行对关联对象的select查询。

        需要注意的是,延迟加载的应用要求,关联对象的查询与主加载对象的查询必须是分别进行的select语句,不能是使用多表连接所进行的select查询。因为,多表连接查询,其实质是对一张表的查询,对由多个表连接后形成的一张表的查询。会一次性将多张表的           所有信息查询出来。

    • 加载配置

        延迟加载配置放在settings标签下 settings在properties之后

        延迟加载的总开关是 lazyLoadingEnabled 默认是false 这种情况下就是直接加载

        侵入式加载的开关是 aggressiveLazyLoading 默认是true 所以只要将总开关打开 就是侵入式加载了

        将侵入式加载的开关关掉 false 那么就是深度延迟了

        <!-- 设置整个应用所使用的常量 -->
        <settings>
            <!-- 延迟加载的总开关 -->
            <setting name="lazyLoadingEnabled" value="true"/>
            <!-- 侵入式延迟加载开关 -->
            <setting name="aggressiveLazyLoading" value="false"/>
        </settings>

     

  • 相关阅读:
    Eclipse配置Maven3.5
    VM搭建Hadoop环境静态IP未起作用
    Word2010制作倒福字
    Word2010制作日历
    【整理】HTML5游戏开发学习笔记(1)- 骰子游戏
    [转载]HTML5开发入门经典教程和案例合集(含视频教程)
    [转载]如何做到 jQuery-free?
    [转载]教你如何塑造JavaScript牛逼形象
    Cloud9免费云IDE代码编辑平台空间支持Node.js,PHP,Python可使用FTP管理
    [转载]PayPal为什么从Java迁移到Node.js,性能提高一倍,文件代码减少44%
  • 原文地址:https://www.cnblogs.com/windbag7/p/9368074.html
Copyright © 2020-2023  润新知