mysatis中子查询剖析

mybatis中查询代码是这样写的

 <resultMap id="riskDTOMap" type="vip.xiaonuo.modular.safety.risk.common.entity.dto.SafetyAllRiskListDTO">
       <result column="id" property="id"></result>
       <result column="org_id" property="orgId"></result>
       <result column="inspect_type" property="inspectType"></result>
       <result column="risk_level" property="riskLevel"></result>
       <result column="responsible_user" property="responsibleUser"></result>
       <result column="risk_descript" property="riskDescript"></result>
       <result column="risk_photo" property="riskPhoto"></result>
       <result column="risk_status" property="riskStatus"></result>
       <result column="create_time" property="createTime"></result>
       <result column="create_user" property="createUser"></result>
       <result column="rectification_time" property="rectificationTime"></result>
       <result column="orgName" property="orgName"></result>
       <result column="responsibleUserName" property="responsibleUserName"></result>
       <result column="createUserName" property="createUserName"></result>
       <result column="risk_name" property="riskName"></result>
       <result column="risk_name_id" property="riskNameId"></result>
        <collection property="recordListDTOS"
                    ofType="vip.xiaonuo.modular.safety.risk.common.entity.dto.SafetyAllRiskRecordListDTO"
                    select="selectRecordDTOs"
                    column="{riskId=id}"/>
    </resultMap>
    
 <select id="selectAllRiskList" resultMap="riskDTOMap">
        SELECT
        risk.id, risk.org_id,risk.inspect_type,risk.risk_level,risk.responsible_user,risk.risk_descript,risk.risk_photo,
        risk.risk_status,risk.create_time,risk.create_user,risk.rectification_time,rname.risk_name,rname.id risk_name_id,
        org.`name` orgName,U1.name responsibleUserName,U2.name createUserName
        FROM
        `safety_risk` risk
        LEFT JOIN
        sys_org org on  risk.org_id = org.id
        LEFT JOIN
        sys_user U1 on U1.id = risk.responsible_user
        LEFT JOIN
        sys_user U2 on U2.id = risk.create_user
        LEFT JOIN
        safety_risk_name rname on risk.risk_name_id = rname.id
        <where>
            <if test="null != riskParam.createUserName and riskParam.createUserName != ''">
                and u2.name like concat('%',#{riskParam.createUserName},'%')
            </if>
            <if test="null != riskParam.riskLevel">
                and risk_level = #{riskParam.riskLevel}
            </if>
            <if test="null != riskParam.riskName and ''!= riskParam.riskName">
                and rname.id =  #{riskParam.riskName}
            </if>
            <if test="null != riskParam.riskStatus">
                and risk_status = #{riskParam.riskStatus}
            </if>
            <if test="null != riskParam.inspectType">
                and inspect_type = #{riskParam.inspectType}
            </if>
            <if test="null != riskParam.orgIds and riskParam.orgIds.size > 0">
                and org_id in
                <foreach collection="riskParam.orgIds" item="e" open="(" close=")" separator=",">
                    #{e}
                </foreach>
            </if>
            <if test="null != riskParam.riskStatues and riskParam.riskStatues.size > 0">
                and risk_status in
                <foreach collection="riskParam.riskStatues" item="e" open="(" close=")" separator=",">
                    #{e}
                </foreach>
            </if>
            <if test="null != riskParam.id">
                and risk.id = #{riskParam.id}
            </if>
            <if test="null != riskParam.ids and riskParam.ids.size > 0">
                and risk.id in
                <foreach collection="riskParam.ids" item="e" open="(" close=")" separator=",">
                    #{e}
                </foreach>
            </if>
            <if test="null != riskParam.createUser">
                and risk.create_user = #{riskParam.createUser}
            </if>
            <if test="null != riskParam.responsibleUser ">
                and risk.responsible_user = #{riskParam.responsibleUser}
            </if>
            <if test="null != riskParam.checkTimeStart and riskParam.checkTimeStart != ''">
                and risk.create_time &gt;= #{riskParam.checkTimeStart}
            </if>
            <if test="null != riskParam.checkTimeEnd and riskParam.checkTimeEnd != ''">
                and risk.create_time &lt;= #{riskParam.checkTimeEnd}
            </if>
            <if test="null != riskParam.rectificationTimeStart and riskParam.rectificationTimeStart != ''">
                and rectification_time &gt;= #{riskParam.rectificationTimeStart}
            </if>
            <if test="null != riskParam.rectificationTimeEnd and riskParam.rectificationTimeEnd != ''">
                and rectification_time &lt;= #{riskParam.rectificationTimeEnd}
            </if>
        </where>
        order by
        risk.create_time desc
    </select>
    
 <select id="selectRecordDTOs" resultType="vip.xiaonuo.modular.safety.risk.common.entity.dto.SafetyAllRiskRecordListDTO">
        SELECT
                safety_risk_record.id recordId,
                risk_id,
                rectification_measure,
                rectification_photo,
                check_status,
                check_descript,
                completion_time,
                delay_day,
                delay_status,
                delay_remark,
                safety_risk_record.create_time recordCreateTime,
                safety_risk_record.create_user,
                safety_risk_record.update_time,
                safety_risk_record.update_user,
                F1.file_object_name rectificationPhotoPath
        from
            safety_risk_record
        LEFT JOIN
            sys_file_info F1 on F1.id = safety_risk_record.rectification_photo
        where
            risk_id = #{riskId}
    </select>

返回实体类

/*
Copyright [2020] [https://www.xiaonuo.vip]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:

1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改Snowy源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处,作者声明等。
4.分发源码时候,请注明软件出处 https://gitee.com/xiaonuobase/snowy
5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/xiaonuobase/snowy
6.若您的项目无法满足以上几点,可申请商业授权,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.modular.safety.risk.common.entity.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 隐患整改
 *
 * @author Eternal
 * @date 2022-09-27 09:21:16
 */
@Data
public class SafetyAllRiskListDTO {
    /**
     * 主键
     */
    private Long id;

    /**
     * 组织机构ID
     */
    private Long orgId;

    /**
     * 组织机构名称
     */
    private String orgName;

    /**
     * 隐患名称
     */
    private String riskName;

    private Long riskNameId;
    /**
     * 检查类型
     */
    private Integer inspectType;

    /**
     * 隐患级别
     */
    private Integer riskLevel;

    /**
     * 整改责任人id
     */
    private Long responsibleUser;

    /**
     * 整改责任人
     */
    private String  responsibleUserName;

    /**
     * 整改责任人Account
     */
    private String responsibleAccount;

    /**
     * 整改期限
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date rectificationTime;

    /**
     * 隐患描述
     */
    private String riskDescript;

    /**
     * 隐患照片
     */
    private String riskPhoto;

    /**
     * 整改核查id
     */
    private Long recordId;

    /**
     * 隐患状态
     */
    private Integer riskStatus;

    /**
     * 检查人姓名
     */
    private String createUserName;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date createTime;

    /**
     * 创建人
     */
    private Long createUser;

    /**
     * 更新时间
     */
    private Date updateTime;

    /**
     * 更新人
     */
    private Long updateUser;

    /**
     * 整改核查列表信息
     */
    private List<SafetyAllRiskRecordListDTO> recordListDTOS;

}


先说结论

再mybatis中这样写子查询,和在循环中写select通过外键查询效果是一样的,效率很低,速度很慢。
通过测试,他有一个懒加载的机制
再例子中:只有用到了recordListDTOS 才会执行子查询


可以看到,这条sql的执行时间不到1s,打印的sql日志也只有主体sql
但是当循环取recordListDTOS时:
打印了一千多条sql进行外键查询,耗时17s

真是坑爹啊▄█▀█●

你可能感兴趣的:(mybatis,java,mysql)