解决需求中的 三级联动

解决需求中的 三级联动

什么是三级联动

所谓三级,即使三个级别,联动代表这三个级别相互依赖与嵌套,唯有这样才能实现三级联动;

在平时生活中,网上填一些表格时就可以预见到,例如:某某省(一级)某某市(二级)某某区(三级);

看到这里就可以快速理解了吧,这就是所谓id三级联动;

如何实现

其实,解决这个需求并不难,首先,三级代表三个属性,也就意味着,你需要三个属性表,现在我们可以举例电商项目的类型;

比如,商品表里面的属性有 商品id 商品名称 商品类型 这个类型就是三级联动里面的最后一个级别,也可以理解成最终类型表,所以商品类型表关联的就是第三级别表的id;

实现步骤

1.先将三个级别分别创建出三张表,先建出来省级表:

省级表id 省名称`

再建出来市级,现在就要注意啦,因为上面我也提到了,如果想联动,那就务必相互依赖,所以,在市级中有三个字段,分别是:

市级id 省级id 市区名称   

以下就以此类推:

区级表:

区级id 市级id 区域名称

 

小结:从上可见,三张表均有相互嵌套相相互依赖的关系,唯有这样才能实现三级联动;

 

使用规则

因为,三级联动需要链接三张表,所以我们需要建立一个自定义返回类(DTO),或者业务拓展类,在这里还是推荐使用DTO;

直接在dao层下建立一个dto包,这个包均是需要多张表链接查询用的;

值得注意的是,如果是两张表链接,那么就可以不使用DTO的方式去返回结果,只要在Mapper层中对应映射关系即可,但是如果超过两张表,那么就需要额外建类了;

如图:

 

 

 在这个类中无疑就是将查询所需字段,全部填写在里面,前提是一定要添加注释,否则这个类将会很乱;

例如:

package com.qyzn.ogpc.dao.dto;

import com.qyzn.ogpc.dao.entity.OpgcSonarticletype;

import java.util.Date;

public class OpgcArticleQueryByTypeDTO {
    //文章类型属性开始 start 。。。
    //文章类型
    private String sonarticletypeNname;

    private Integer articleId;

    private String articleHeadline;

    private String articeRichtext;

    private Integer articeRead;

    private Integer articeMode;

    private Integer articeEndorse;

    private Integer userId;

    private Date articePublishtime;
    /**
     * 第三级表外键对象属性
     */
    private OpgcSonarticletype sonarticletype;

    private String articletypeCover;

    private Integer articeCommentnum;

    private String articeResource;

    private Double articePrice;

    private Integer articeRecommend;
    //文章类型属性结束 end 。。。

    //一级属性开始 start。。。
    private Integer articletypeId;

    private String articletypeName;
    //一级属性结束 end。。。

    //二级属性开始 start。。。
    private Integer childtypeId;

    private Integer parentArticletypeId;

    private String childtypeName;
    //二级属性结束 end。。。

    //三级属性开始 start。。。
    private Integer sonarticletypeId;

    private String sonarticletypeName;

    private Integer parentChildtypeId;
    //三级属性结束 end。。。


    public String getSonarticletypeNname() {
        return sonarticletypeNname;
    }

    public void setSonarticletypeNname(String sonarticletypeNname) {
        this.sonarticletypeNname = sonarticletypeNname;
    }

    public Integer getArticleId() {
        return articleId;
    }

    public void setArticleId(Integer articleId) {
        this.articleId = articleId;
    }

    public String getArticleHeadline() {
        return articleHeadline;
    }

    public void setArticleHeadline(String articleHeadline) {
        this.articleHeadline = articleHeadline;
    }

    public String getArticeRichtext() {
        return articeRichtext;
    }

    public void setArticeRichtext(String articeRichtext) {
        this.articeRichtext = articeRichtext;
    }

    public Integer getArticeRead() {
        return articeRead;
    }

    public void setArticeRead(Integer articeRead) {
        this.articeRead = articeRead;
    }

    public Integer getArticeMode() {
        return articeMode;
    }

    public void setArticeMode(Integer articeMode) {
        this.articeMode = articeMode;
    }

    public Integer getArticeEndorse() {
        return articeEndorse;
    }

    public void setArticeEndorse(Integer articeEndorse) {
        this.articeEndorse = articeEndorse;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Date getArticePublishtime() {
        return articePublishtime;
    }

    public void setArticePublishtime(Date articePublishtime) {
        this.articePublishtime = articePublishtime;
    }

    public OpgcSonarticletype getSonarticletype() {
        return sonarticletype;
    }

    public void setSonarticletype(OpgcSonarticletype sonarticletype) {
        this.sonarticletype = sonarticletype;
    }

    public String getArticletypeCover() {
        return articletypeCover;
    }

    public void setArticletypeCover(String articletypeCover) {
        this.articletypeCover = articletypeCover;
    }

    public Integer getArticeCommentnum() {
        return articeCommentnum;
    }

    public void setArticeCommentnum(Integer articeCommentnum) {
        this.articeCommentnum = articeCommentnum;
    }

    public String getArticeResource() {
        return articeResource;
    }

    public void setArticeResource(String articeResource) {
        this.articeResource = articeResource;
    }

    public Double getArticePrice() {
        return articePrice;
    }

    public void setArticePrice(Double articePrice) {
        this.articePrice = articePrice;
    }

    public Integer getArticeRecommend() {
        return articeRecommend;
    }

    public void setArticeRecommend(Integer articeRecommend) {
        this.articeRecommend = articeRecommend;
    }

    public Integer getArticletypeId() {
        return articletypeId;
    }

    public void setArticletypeId(Integer articletypeId) {
        this.articletypeId = articletypeId;
    }

    public String getArticletypeName() {
        return articletypeName;
    }

    public void setArticletypeName(String articletypeName) {
        this.articletypeName = articletypeName;
    }

    public Integer getChildtypeId() {
        return childtypeId;
    }

    public void setChildtypeId(Integer childtypeId) {
        this.childtypeId = childtypeId;
    }

    public Integer getParentArticletypeId() {
        return parentArticletypeId;
    }

    public void setParentArticletypeId(Integer parentArticletypeId) {
        this.parentArticletypeId = parentArticletypeId;
    }

    public String getChildtypeName() {
        return childtypeName;
    }

    public void setChildtypeName(String childtypeName) {
        this.childtypeName = childtypeName;
    }

    public Integer getSonarticletypeId() {
        return sonarticletypeId;
    }

    public void setSonarticletypeId(Integer sonarticletypeId) {
        this.sonarticletypeId = sonarticletypeId;
    }

    public String getSonarticletypeName() {
        return sonarticletypeName;
    }

    public void setSonarticletypeName(String sonarticletypeName) {
        this.sonarticletypeName = sonarticletypeName;
    }

    public Integer getParentChildtypeId() {
        return parentChildtypeId;
    }

    public void setParentChildtypeId(Integer parentChildtypeId) {
        this.parentChildtypeId = parentChildtypeId;
    }

    @Override
    public String toString() {
        return "OpgcArticleQueryByTypeDTO{" +
                "sonarticletypeNname='" + sonarticletypeNname + '\'' +
                ", articleId=" + articleId +
                ", articleHeadline='" + articleHeadline + '\'' +
                ", articeRichtext='" + articeRichtext + '\'' +
                ", articeRead=" + articeRead +
                ", articeMode=" + articeMode +
                ", articeEndorse=" + articeEndorse +
                ", userId=" + userId +
                ", articePublishtime=" + articePublishtime +
                ", sonarticletype=" + sonarticletype +
                ", articletypeCover='" + articletypeCover + '\'' +
                ", articeCommentnum=" + articeCommentnum +
                ", articeResource='" + articeResource + '\'' +
                ", articePrice=" + articePrice +
                ", articeRecommend=" + articeRecommend +
                ", articletypeId=" + articletypeId +
                ", articletypeName='" + articletypeName + '\'' +
                ", childtypeId=" + childtypeId +
                ", parentArticletypeId=" + parentArticletypeId +
                ", childtypeName='" + childtypeName + '\'' +
                ", sonarticletypeId=" + sonarticletypeId +
                ", sonarticletypeName='" + sonarticletypeName + '\'' +
                ", parentChildtypeId=" + parentChildtypeId +
                '}';
    }
}

而在Mapper.xml文件中,需要返回的接口,直接返回DTO的类即可:

    <select id="SelectAllByType" resultType="com.qyzn.ogpc.dao.dto.OpgcArticleQueryByTypeDTO">

接口编写

在接口这边,因为是三级联动,所以呢,我们需要提供三个参数,再配上动态sql去使用,才能达到联动的效果!

先看dao层接口:

/**
     * 三级联动查询
     * @param articletypeId 属于一级类型id
     * @param childtypeId 属于二级类型id
     * @param sonarticletypeId 属于 三级类型id
     * @return mapper xml层建立返回的 dto 对象,包含的博文[商品]数据、各层级数据
     */
    List<OpgcArticleQueryByTypeDTO> SelectAllByType(@Param("articletypeId")Integer articletypeId, @Param("childtypeId") Integer childtypeId, @Param("sonarticletypeId")Integer sonarticletypeId);

Service:

/**
     * 三级联动查询
     * @param articletypeId 属于一级类型id
     * @param childtypeId 属于二级类型id
     * @param sonarticletypeId 属于 三级类型id
     * @return
     */
    Map<String , Object> SelectAllByType(int articletypeId, int childtypeId, int sonarticletypeId);

impl:

/**
     * 三级联动查询
     * @param articletypeId 属于一级类型id
     * @param childtypeId 属于二级类型id
     * @param sonarticletypeId 属于 三级类型id
     * @return
     */
    @Override
    public Map<String, Object> SelectAllByType(int articletypeId, int childtypeId, int sonarticletypeId) {
        Map<String , Object> map = new ConcurrentHashMap<>();
        int code = 200;
        String msg = "查询成功";
        try {
            List<OpgcArticleQueryByTypeDTO> dtos = opgcArticleMapper.SelectAllByType(articletypeId, childtypeId, sonarticletypeId);
            map.put("data",dtos);
        }catch (Exception e)
        {
            code = 500;
            msg = "查询错误";
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally {
            map.put("code",code);
            map.put("msg",msg);
        }
        return map;
    }

Controller:

/**
     * 现在三级联动查询基本结束,只用建立测试就行
     * @param articletypeId 一级 ID
     * @param childtypeId 二级 ID
     * @param sonarticletypeId 三级 ID
     * @return 返回数据结果
     */
    @ApiOperation(value = "三级联动,建立出返回值的dto类,抽取出共有的属性")
    @GetMapping("/SelectAllByType")
    public Map<String , Object> SelectAllByType(@RequestParam("articletypeId")Integer articletypeId, @RequestParam("childtypeId") Integer childtypeId, @RequestParam("sonarticletypeId")Integer sonarticletypeId){
        return opgcArticleService.SelectAllByType(articletypeId,childtypeId,sonarticletypeId);
    };

Mapper.xml:

 <!-- 建立出返回值的 dto 类,抽取出共有的属性,返回值中建立好了列的别名,别名和 dto 的对象属性一致,便直接返回 resultType -->
    <select id="SelectAllByType" resultType="com.qyzn.ogpc.dao.dto.OpgcArticleQueryByTypeDTO">
        SELECT
        q.artice_commentnum articeCommentnum,q.artice_endorse articeEndorse,q.artice_mode articeMode,q.artice_price articePrice,q.artice_publishtime articePublishtime,q.artice_read articeRead,q.artice_recommend articeRecommend,q.artice_resource articeResource,q.artice_richtext articeRichtext,q.article_headline articleHeadline,q.article_id articleId,q.articletype_cover articletypeCover,q.sonarticletype_id articeSonarticletypeId , q.user_id userId,
        a.articletype_id articletypeId,a.articletype_name articletypeName,
        b.childtype_id childtypeId,b.childtype_name childtypeName,b.articletype_id parentArticletypeId ,
        c.sonarticletype_id sonarticletypeId,c.sonarticletype_name sonarticletypeName,c.childtype_id parentChildtypeId
        FROM
        opgc_article q
        left join opgc_sonarticletype c on q.sonarticletype_id = c.sonarticletype_id
        left join opgc_childtype b on b.childtype_id = c.childtype_id
        left join opgc_articletype a on a.articletype_id = b.childtype_id
        where  1 = 1
        <if test="articletypeId != null">
            and a.articletype_id = #{articletypeId}
        </if>
        <if test="childtypeId != null">
            and b.childtype_id = #{childtypeId}
        </if>
        <if test="sonarticletypeId != null">
            and c.sonarticletype_id = #{sonarticletypeId}
        </if>
    </select>

根据动态sql的条件,传入三个不同的参数,跟随变化而变化,就此达到了三级联动的目的

posted @ 2019-09-02 14:35  StanleyBlogs  阅读(2190)  评论(4编辑  收藏  举报