spring boot mybatis 一对多查询

背景

在开发工程中经常会遇到一对多数据的情况,在查询公司信息列表信息时,需要把多个公司的标签也显示在列表中。这时我们就可以通过mybatis构建上述需求中的数据信息。

需求

一对多查询通常涉及到两个实体类,一个是一方实体类,一个是多方实体类。例如,一个公司可以拥有多个标签,那么公司就是一方实体类,标签就是多方实体类。
在查询公司列表信息时,除公司基本信息外,也要返回公司的多个标签信息

第一种实现

使用sql中的关联查询出全部数据,然后在使用collection标签对返回值进行格式化操作。部分代码如下:

 	<!-- 映射结果集 SerCompanyVO -->
    <resultMap id="resultMap" type="SerCompanyVO">
        <id column="company_id" property="companyId" jdbcType="INTEGER" />
        <result column="company_name" property="companyName" jdbcType="VARCHAR" />
        <result column="company_code" property="companyCode" jdbcType="VARCHAR" />
        <result column="company_msg" property="companyMsg" jdbcType="VARCHAR" />
        <result column="company_crdt" property="companyCrdt" jdbcType="VARCHAR" />
    </resultMap>

    <!-- 一对多查询 join 结果集 -->
    <resultMap id="tagResultMap" type="SerCompanyVO" extends="resultMap">
        <collection property="list" ofType="SerCompanyTagVO">
            <id column="tag_id" property="tagId" jdbcType="INTEGER" />
            <result column="tag_name" property="tagName" jdbcType="VARCHAR" />
            <result column="tag_msg" property="tagMsg" jdbcType="VARCHAR" />
        </collection>
    </resultMap>
     
     <!-- 一对多查询 join 语句-->
    <select id="selectSerCompanyListTagJoin" resultMap="tagResultMap">
        SELECT c.company_id,c.company_name, company_code, company_msg, company_crdt,
        t.tag_id,t.tag_msg,t.tag_name FROM ser_company c
        LEFT JOIN ser_company_tag t ON c.company_id = t.company_id
    </select>

通过 selectSerCompanyListTagJoin 查询到公司信息及关联的公司标签信息。然后使用tagResultMap将结果集映射到SerCompanyVO实体类中。其中list 是 SerCompanyVO实体类中的标签类的集合。在接口调用后返回如下数据:
在这里插入图片描述

第二种实现

使用一个接口查询出主表数据,然后通过association标签进行二次子查询,在将关联数据返回。具体代码如下:

<!-- 映射结果集 SerCompanyVO -->
    <resultMap id="resultMap" type="SerCompanyVO">
        <id column="company_id" property="companyId" jdbcType="INTEGER" />
        <result column="company_name" property="companyName" jdbcType="VARCHAR" />
        <result column="company_code" property="companyCode" jdbcType="VARCHAR" />
        <result column="company_msg" property="companyMsg" jdbcType="VARCHAR" />
        <result column="company_crdt" property="companyCrdt" jdbcType="VARCHAR" />
    </resultMap>

    <!-- 映射结果集 SerCompanyTagVO -->
    <resultMap id="serCompanyTagResultMap" type="SerCompanyTagVO">
        <id column="tag_id" property="tagId" jdbcType="INTEGER" />
        <result column="tag_name" property="tagName" jdbcType="VARCHAR" />
        <result column="tag_msg" property="tagMsg" jdbcType="VARCHAR" />
        <result column="company_id" property="companyId" jdbcType="INTEGER" />
    </resultMap>

    <!-- 一对多查询 asso 结果集 -->
    <resultMap id="assoResultMap" type="com.study.model.SerCompanyVO" extends="resultMap">
        <association property="list"  column="company_id" select="getSerCompanyTag"/>
    </resultMap>

    <!-- 一对多查询  asso方式 子表查询 -->
    <select id="selectSerCompanyListTagAsso" resultMap="assoResultMap">
        select company_id,company_name, company_code, company_msg, company_crdt from ser_company
    </select>

    <!-- 一对多查询  asso方式 主表查询 -->
    <select id="getSerCompanyTag" resultMap="serCompanyTagResultMap" parameterType="int">
          select t.company_id,t.tag_id,t.tag_msg,t.tag_name from ser_company_tag t where t.company_id=#{companyId}
    </select>

首先调用selectSerCompanyListTagAsso查询出主表信息,在返回结果集时,通过association调用设置好的select子查询进行二次查询。这里为getSerCompanyTag接口。然后在重组在结果集中。结果如下:

在这里插入图片描述

总结

第二种方式不太使用适用于列表查询接口中,主表返回多少条数据,子查询就会进行多少次查询。比较浪费数据库资源,所以推荐使用第一种方式进行查询。

第一种方式中必要时请使用inner join关联,这里仅为示例一对多返回。

实体类源码

@Alias("SerCompanyTagVO")
public class SerCompanyTagVO {
    
    

    private int tagId;
    private String tagName;
    private String tagMsg;
    private int companyId;

    public int getTagId() {
    
    
        return tagId;
    }

    public void setTagId(int tagId) {
    
    
        this.tagId = tagId;
    }

    public String getTagName() {
    
    
        return tagName;
    }

    public void setTagName(String tagName) {
    
    
        this.tagName = tagName;
    }

    public String getTagMsg() {
    
    
        return tagMsg;
    }

    public void setTagMsg(String tagMsg) {
    
    
        this.tagMsg = tagMsg;
    }

    public int getCompanyId() {
    
    
        return companyId;
    }

    public void setCompanyId(int companyId) {
    
    
        this.companyId = companyId;
    }
}
@Alias("SerCompanyVO")
public class SerCompanyVO {
    
    

    private int companyId;
    private String companyName;
    private String companyCode;
    private String companyMsg;
    private String companyCrdt;
    private List<SerCompanyTagVO> list;

    private SerCompanyTagVO serCompanyTagVO;


    public int getCompanyId() {
    
    
        return companyId;
    }

    public void setCompanyId(int companyId) {
    
    
        this.companyId = companyId;
    }

    public String getCompanyName() {
    
    
        return companyName;
    }

    public void setCompanyName(String companyName) {
    
    
        this.companyName = companyName;
    }

    public String getCompanyCode() {
    
    
        return companyCode;
    }

    public void setCompanyCode(String companyCode) {
    
    
        this.companyCode = companyCode;
    }

    public String getCompanyMsg() {
    
    
        return companyMsg;
    }

    public void setCompanyMsg(String companyMsg) {
    
    
        this.companyMsg = companyMsg;
    }

    public String getCompanyCrdt() {
    
    
        return companyCrdt;
    }

    public void setCompanyCrdt(String companyCrdt) {
    
    
        this.companyCrdt = companyCrdt;
    }

    public List<SerCompanyTagVO> getList() {
    
    
        return list;
    }

    public void setList(List<SerCompanyTagVO> list) {
    
    
        this.list = list;
    }

    public SerCompanyTagVO getSerCompanyTagVO() {
    
    
        return serCompanyTagVO;
    }

    public void setSerCompanyTagVO(SerCompanyTagVO serCompanyTagVO) {
    
    
        this.serCompanyTagVO = serCompanyTagVO;
    }
}

dao层源码

@Mapper
public interface SerCompanyMapper {

    /**
     * 一对多查询公司信息 包含公司标签 join 方式
     * @return
     */
    List<SerCompanyVO> selectSerCompanyListTagJoin();

    /**
     * 一对多查询公司信息 包含公司标签 asso 方式
     * @return
     */
    List<SerCompanyVO> selectSerCompanyListTagAsso();

    /**
     * 一对多查询公司信息 包含公司标签 asso 方式
     * @param companyId
     * @return
     */
    SerCompanyTagVO getSerCompanyTag(int companyId);
}

写在最后

开源是一种美德,尽早加入开源社区,共建美好生态!

猜你喜欢

转载自blog.csdn.net/qq_36378416/article/details/127769485