mybatis 一对多查询collection的两种查询方式

第一种 一次性查询出结果然后封装(该方法不能在主表sql语句分页)

  • 直接用collection标签映射,一次性查询所有记录,
  • 其中tags、roles、files、对应实体类中的成员
  • 查询结果是多条记录,然后mybatis根据主表ID封装

注意:这里不能采用分页查询。因为执行sql查询出的所有记录是未封装的记录。而我们想要的是封装后的分页查询

<resultMap type="KlbDocument" id="KlbDocumentResultById">
        <id     property="documentId"       column="document_id"  />
        <result property="docName"       column="doc_Name"   />
        <result property="categoryId"     column="category_id"   />
        <result property="validity"  column="validity"  />
        <result property="hot"          column="hot"          />
        <result property="comment"       column="comment"       />
        <result property="delFlag"     column="del_flag"     />
        <result property="createTime"       column="create_time"       />
        <result property="updateTime"      column="update_time"     />
        <result property="createBy"      column="create_by"     />
        <result property="updateBy"    column="update_by"   />
        <collection property="tags" ofType="KlbDocTag" >
            <id     property="id"       column="tag_id"  />
            <result property="tagName"       column="tag_name"      />
        </collection>
        <collection  property="roles"  ofType="KlbDocRole" >
            <id     property="id"       column="role_id"  />
            <result property="roleName"       column="role_name"      />
        </collection>
        <collection  property="files"  ofType="KlbFile" >
            <id     property="fileId"       column="file_id"  />
            <result property="fileName"       column="file_name"      />
            <result property="url"       column="url"      />
        </collection>
    </resultMap>
	<select id="selectDocumentById" parameterType="KlbDocument" resultMap="KlbDocumentResultById">
        SELECT d.document_id,d.doc_name,c.category_id,c.cate_name,d.create_time,d.create_by,d.hot,d.validity,dt.id as tag_id,tag.tag_name,dc.id as role_id,r.role_name,file.file_id,file.file_name,file.url
        FROM klb_document d

        LEFT JOIN klb_doc_tag dt ON dt.document_id = d.document_id

        LEFT JOIN klb_tag tag on tag.tag_id = dt.tag_id

        LEFT JOIN klb_file file on file.business_id = d.document_id

        LEFT JOIN klb_doc_role dc on dc.document_id = d.document_id

        LEFT JOIN sys_role r on r.role_id = dc.role_id

        LEFT JOIN klb_category c on c.category_id = d.category_id

        where d.del_flag = '1' and file.source = 'doc' and d.document_id = #{documentId} and d.status = 1
    </select>

第二种 嵌套查询,先查主表,然后根据主表查询结果,查询子表(主表sql可以分页)

  • 先用主表查询,查询出记录,然后遍历记录去子表查询。主表查询时可以加分页。
  • 其中tags、roles、对应实体类中的成员,
  • collection select对应具体某条查询语句,column中前一个值是定义的变量名 后一个值是主表查询出的结果中的字段
  • 当主表查询需要和子表联查时需要加GROUP BY对查询结果根据主键分组
<resultMap type="KlbDocument" id="KlbDocumentResult">
        <id     property="documentId"       column="document_id"  />
        <result property="docName"       column="doc_Name"   />
        <result property="categoryId"     column="category_id"   />
        <result property="validity"  column="validity"  />
        <result property="hot"          column="hot"          />
        <result property="comment"       column="comment"       />
        <result property="delFlag"     column="del_flag"     />
        <result property="createTime"       column="create_time"       />
        <result property="updateTime"      column="update_time"     />
        <result property="createBy"      column="create_by"     />
        <result property="updateBy"    column="update_by"   />
        <collection property="tags" javaType="java.util.ArrayList" ofType="KlbDocTag"
                    select="com.chinaunicom.system.mapper.base.KlbDocumentMapper.selectTagList" column="{documentId=document_id" />
        <collection property="roles" javaType="java.util.ArrayList" ofType="KlbDocRole"
                    select="com.chinaunicom.system.mapper.base.KlbDocumentMapper.selectRoleList" column="{documentId=document_id" />
    </resultMap>
	<!--根据主表查询,注意如果主表查询是多表联查,需要用GROUP BY 更具主表主键分组,保证主表查询出的记录是不重复的-->
	<select id="selectDocumentList" parameterType="KlbDocument" resultMap="KlbDocumentResult">
       SELECT d.document_id,d.doc_name,d.category_id,c.cate_name,d.create_by,d.hot,d.validity,d.create_time
         FROM klb_document d
         LEFT JOIN klb_doc_tag dt
         ON dt.document_id = d.document_id
         LEFT JOIN klb_tag tag
         ON tag.tag_id = dt.tag_id
         LEFT JOIN klb_file file
         ON file.business_id = d.document_id
         LEFT JOIN klb_doc_role dc
         ON dc.document_id = d.document_id
         LEFT JOIN sys_role r
         ON r.role_id = dc.role_id
         LEFT JOIN klb_category c
         ON c.category_id = d.category_id
         where d.del_flag = '1' and file.source = 'doc' and d.status = 1

        <if test="documentId != null and documentId != 0">
            AND d.document_id = #{documentId}
        </if>
        <if test="docName != null and docName != ''">
            AND d.doc_name like concat('%', #{docName}, '%')
        </if>
        <if test="categoryId != null and categoryId != 0">
            AND d.category_id = #{categoryId}
        </if>
        <if test="createBy != null and createBy != ''">
            AND d.create_by = #{createBy}
        </if>
        <if test="selectTagId != null and selectTagId != 0">
            AND dt.tag_id = #{selectTagId}
        </if>
        <if test="fileSuffix != null and fileSuffix != ''">
            AND file.file_suffix = #{fileSuffix}
        </if>
        <if test="hot != null">
            AND d.hot = #{hot}
        </if>

        <if test="roleId != null and roleId.length > 0">
            AND r.role_id in
            <foreach item="item" collection="roleId" separator="," open="(" close=")" index="">
                #{item}
            </foreach>
        </if>
         GROUP BY d.document_id ORDER BY d.create_time
    </select>
    
    
    <!--根据主表传入主键,去子表查询-->
    <select id="selectTagList" resultType="KlbDocTag">
        SELECT
            dt.tag_id,tag.tag_name
        FROM
            klb_doc_tag dt

        LEFT JOIN klb_tag tag ON tag.tag_id = dt.tag_id
        WHERE dt.document_id = #{documentId}
    </select>
	<!--根据主表传入主键,去子表查询-->
    <select id="selectRoleList" resultType="KlbDocRole">
        SELECT
            dc.role_id,
            r.role_name
        FROM
            klb_doc_role dc
        LEFT JOIN sys_role r ON r.role_id = dc.role_id
        WHERE
            dc.document_id = #{documentId}
    </select>
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis中,进行一对多查询可以使用两种方式:分别是使用嵌套查询和使用关联查询。具体的查询语句可以根据实际情况来选择使用哪种方式。 1. 嵌套查询: 在进行一对多查询时,可以使用嵌套查询来获取关联表的数据。这种方式需要在Mapper文件中定义多个SQL语句,并使用resultMap来映射结果。 例如,假设我们有部门(Department)表和员工(Employee)表,一个部门有多个员工,我们想要查询部门及其对应的员工列表,可以使用以下SQL语句: ``` <!-- 定义查询部门及其员工的SQL语句 --> <select id="getDepartmentWithEmployees" resultMap="departmentResultMap"> SELECT d.id, d.name, e.id AS employee_id, e.name AS employee_name FROM department d LEFT JOIN employee e ON d.id = e.department_id </select> <!-- 定义结果映射 --> <resultMap id="departmentResultMap" type="Department"> <id property="id" column="id"/> <result property="name" column="name"/> <collection property="employees" ofType="Employee"> <id property="id" column="employee_id"/> <result property="name" column="employee_name"/> </collection> </resultMap> ``` 在这个例子中,我们定义了一个名为`getDepartmentWithEmployees`的查询语句,通过左连接来关联部门表和员工表,并使用resultMap来映射查询结果。部门与员工之间的关系通过嵌套的collection来表示。 2. 关联查询: 使用关联查询可以在一条SQL语句中获取关联表的数据,这种方式可以减少数据库的查询次数,提高性能。关联查询可以使用MyBatis的动态SQL来实现。 例如,我们可以使用以下SQL语句来实现部门和员工的关联查询: ``` <!-- 定义关联查询 --> <select id="getDepartmentWithEmployees" resultMap="departmentResultMap"> SELECT d.id, d.name, e.id AS employee_id, e.name AS employee_name FROM department d LEFT JOIN employee e ON d.id = e.department_id WHERE d.id = #{id} </select> ``` 在这个例子中,我们使用了LEFT JOIN来关联部门表和员工表,并通过WHERE语句来限定查询结果。通过这种方式,我们可以一次性获取到部门及其对应的员工列表。 请根据实际需要选择使用嵌套查询还是关联查询,并根据自己的数据表结构和需求来编写相应的SQL语句。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值