zoukankan      html  css  js  c++  java
  • 关于mybatis的关联查询


    关联(association)查询: 关联查询出一的一方
    主要是针对查询数据时,顺带查询其关联的一的一方,意思是:
    1. 查询多的一方的时候,顺带查询出一的一方,比如查询员工的时候,顺带查询所属的部门
    就是多对一的情况
    2.一对一的情况,比如查询员工的时候,顺带查询出身份信息

    在mybatis中,总的做法就是利用association这个select元素的子元素来实现

    第一种情况:
    没有用到association,主要用的是ognl这个对象图导航语言的技术.
    这种写法的特点:
    1. sql语句是一次性把两个表的数据都查询出来
    2. sql语句只有一个,只执行一次sql语句
    3.利用resultMap来进行映射处理
    4. 实体类关联的属性,利用导航的配置,比如property="dept.id"
    4.1 dept这个是Employee实体类中的属性的名字
    4.2 dept.id这个id是dept属性对应的另外一个实体类的属性名
    类似于el表达式的写法

    Mapper文件中写入
      <resultMap id="getEmpByIdWithDeptResultMap" type="com.entity.Employee">
            <id column="eid" property="id"></id>
            <result column="username" property="username"></result>
            <result column="deptid" property="deptId"/>
    
            <result column="id" property="dept.id"/>
            <result column="deptname" property="dept.deptname"/>
        </resultMap>
    
        <select id="getEmpById" resultMap="getEmpByIdWithDeptResultMap">
        select e.id as eid ,
        e.username,e.deptid,
               d.id ,
               d.deptname
        from employee e
            left join dept d
        on e.deptid = d.id
        where e.id = #{id}
        </select>
    

      



    第二种情况:
    利用association来处理关联查询
    做法是这样的.
    1.写一个sql语句,此语句是把两个表的数据都查询出来
    2.关联实体的映射是靠association + resultmap属性
    2.1 resultmap属性的值是另外一个独立的resultMap的配置
    3.association的property属性的值是Employee实体的属性名
    相对于第一种的好处是association的resultMap属性值对应的resultMap设置可以重用

     <resultMap id="getEmpByIdWithDeptResultMap2" type="com.entity.Employee">
             <id column="eid" property="id"></id>
             <result column="username" property="username"></result>
             <result column="deptid" property="deptId"/>
    
             <association property="dept" resultMap="basicDeptResultMap"></association>
         </resultMap>
    
         <resultMap id="basicDeptResultMap" type="com.entity.Dept">
             <id column="id" property="id"></id>
             <result column="deptname" property="deptname"></result>
         </resultMap>
    
    
         <select id="getEmpById" resultMap="getEmpByIdWithDeptResultMap2">
             select e.id as eid ,e.username,e.deptid,
                    d.id ,d.deptname
             from employee e
                      left join dept d
                                on e.deptid = d.id
             where e.id = #{id}
         </select>


    第三种情况:
    特点如下:
    1.sql语句还是两个表的记录都查询出来
    2. association没有resultMap属性值的设置
    3. 直接在association内部配置关联实体(Dept类)的映射配置

    跟第二种比较,不能重用关联实体的映射配置


    <resultMap id="getEmpByIdWithDeptResultMap2" type="com.entity.Employee">
         <id column="eid" property="id"></id>
         <result column="username" property="username"></result>
         <result column="deptid" property="deptId"/>
    
         <association property="dept">
             <id column="id" property="id"></id>
             <result column="deptname" property="deptname"></result>
         </association>
     </resultMap>
    
    
     <select id="getEmpById" resultMap="getEmpByIdWithDeptResultMap2">
         select e.id as eid,
                e.username,
                e.deptid,
                d.id,
                d.deptname
         from employee e
                  left join dept d
                            on e.deptid = d.id
         where e.id = #{id}
     </select>
    

      



    第四种情况:
    特点:
    1.有两个sql语句
    1.1 第一个sql语句是查询子表的记录
    1.2 第二个sql语句是查询父表(也就是一的一方的信息)
    2.association必须设置select属性为查询一的一方的select元素的id值
    3.association的column属性的值设定为子表的外键列
    4. 一的一方的映射配置是靠另外一个select元素中设定的resultType或者resultMap来完成映射的
    4.1 一的一方的结果类型跟子的属性的类型应该是兼容(一般是一样的,在案例中就都是Dept类)

    <resultMap id="getEmpByIdWithDeptResultMap3" type="com.entity.Employee">
         <id column="eid" property="id"></id>
         <result column="username" property="username"></result>
         <result column="deptid" property="deptId"/>
    
         <association property="dept" select="getDeptById" column="deptid">
         </association>
     </resultMap>
    
     <resultMap id="basicDeptResultMap" type="com.entity.Dept">
         <id column="id" property="id"></id>
         <result column="deptname" property="deptname"></result>
     </resultMap>
    
     <select id="getEmpById" resultMap="getEmpByIdWithDeptResultMap3" >
         select e.id as eid ,e.username,e.deptid
               from employee  e where e.id = #{id}
     </select>
    
     <select id="getDeptById" resultMap="basicDeptResultMap">
        select id,deptname from dept where id = #{id}
     </select>




    演示n+1查询,这种情况尽量避免出现

    1.可以用内嵌resultmap解决
    2.内部用缓存(cache)解决一部分.


     <resultMap id="NPlusOneEmpResultMap"
                type="com.entity.Employee">
         <id column="eid" property="id"></id>
         <result column="username" property="username"/>
         <result column="deptid" property="deptId"/>
         <association property="dept" select="NPlusOneDeptResultMap" column="deptid"/>
     </resultMap>
    
    
     <select id="NPlusOneDeptResultMap"
             resultType="com.entity.Dept">
             select id,deptname from dept where id = #{id}
     </select>
     <select id="getEmps" resultMap="NPlusOneEmpResultMap">
    
         select id as eid,
                username ,
                deptid from employee e
    
     </select>
    

      

    
    
  • 相关阅读:
    定时器
    sortable.js 华丽丽的排序
    jqGrid一些操作
    session 共享
    数组排序 和 二分法查找
    关于map
    文件导入
    文件导出
    文件下载
    float 保留两位小数
  • 原文地址:https://www.cnblogs.com/LixiaoFeng1650062546/p/11642549.html
Copyright © 2011-2022 走看看