关于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>

  

猜你喜欢

转载自www.cnblogs.com/LixiaoFeng1650062546/p/11642549.html