zoukankan      html  css  js  c++  java
  • 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>

     

  • 相关阅读:
    盒子垂直水平居中
    Sahi (2) —— https/SSL配置(102 Tutorial)
    Sahi (1) —— 快速入门(101 Tutorial)
    组织分析(1)——介绍
    Java Servlet (1) —— Filter过滤请求与响应
    CAS (8) —— Mac下配置CAS到JBoss EAP 6.4(6.x)的Standalone模式(服务端)
    JBoss Wildfly (1) —— 7.2.0.Final编译
    CAS (7) —— Mac下配置CAS 4.x的JPATicketRegistry(服务端)
    CAS (6) —— Nginx代理模式下浏览器访问CAS服务器网络顺序图详解
    CAS (5) —— Nginx代理模式下浏览器访问CAS服务器配置详解
  • 原文地址:https://www.cnblogs.com/windbag7/p/9368074.html
Copyright © 2011-2022 走看看