1. 程式人生 > >mybatis 查詢優化主子表查詢之association和collection

mybatis 查詢優化主子表查詢之association和collection

employ area 技術 type col orm 所有 parameter ade

很多開發人員之所以編寫出低效的應用,有一大原因是並不理解怎樣編寫高效的SQL。以訂單查詢為例,我們經常需要查詢某個用戶的訂單以及訂單明細,並且以樹形方式展現如下:

技術分享圖片

對於這種性質的功能,很多開發人員的做法是先查詢主表,然後根據主表去循環子表,如下所示:

List<Department> depts = DepartmentMapper.queryDept();
for (Department dept: depts) {
    dept.setEmps(EmployeeMapper.queryEmp(dept.id));
}

這種做法就是典型的過程性編程思維,它不僅在更改查詢條件或字段時維護性差、不支持兩個表的查詢條件,而且性能低下,主表有幾條記錄就會導致請求數據庫幾次,不僅應用響應時間長,服務器也耗費了更多的資源。更好的做法是一次性查詢會所有符合條件的記錄,然後再應用中進行拆分並組裝,主流的ORM框架幾乎都支持這些模式,以使用最廣泛的Mybatis為例,其結果映射resultMap中的association(用於一對一和多對一)和collection(用於一對多)元素支持自動將二位結果映射為主子對象。如下所示:

<mapper namespace="chapter6.dao.DepartmentMapper">
    <!-- 嵌套結果集的方式,使用collection標簽定義關聯的集合類型的屬性封裝規則 -->
    <resultMap type="chapter6.Department" id="MyDept">
        <id column="did" property="id"/>
        <result column="dept_name" property="departmentName"/>
        <
collection property="emps" ofType="chapter6.Employee"> <id column="eid" property="id"/> <result column="last_name" property="lastName"/> <result column="email" property="email"/> <result column="gender" property="gender"/> </
collection> </resultMap> <select id="queryDept" resultMap="MyDept" > SELECT d.id did, d.dept_name dept_name, e.id, e.last_name last_name, e.email email, e.gender gender FROM tbl_dept d LEFT JOIN tbl_employee e ON d.id = e.d_id </select> </mapper>

association同樣可以實現相同功能,不過明細表是主表,如下所示:

<mapper namespace="com.abc.mapper.StudentMapper">
    <select id="getById" parameterType="int"
        resultMap="studentResultMap">
        select s.id s_id,
        s.name s_name,
        s.gender s_gender,
        s.major s_major,
        s.grade s_grade,
        t.id t_id,
        t.name t_name,
        t.gender t_gender,
        t.title t_title,
        t.research_area t_research_area
        from student s left join teacher t
        on s.supervisor_id = t.id
        where s.id=#{id}
    </select>
    <resultMap id="studentResultMap" type="Student">
        <id property="id" column="s_id" />
        <result property="name" column="s_name" />
        <result property="gender" column="s_gender" />
        <result property="major" column="s_major" />
        <result property="grade" column="s_grade" />
        <!--使用resultMap屬性引用下面的教師實體映射 -->
        <association property="supervisor" javaType="Teacher"
            resultMap="supervisorResultMap" />
    </resultMap>
    <!--教師實體映射 -->
    <resultMap id="supervisorResultMap" type="Teacher">
        <id property="id" column="t_id" />
        <result property="name" column="t_name" />
        <result property="gender" column="t_gender" />
        <result property="researchArea" column="t_research_area" />
        <result property="title" column="t_title" />
    </resultMap>
</mapper>

mybatis 查詢優化主子表查詢之association和collection