MyBatis一对多查询<collection>三表三层查询

首先,将数据表列出

第一张表INDICATIONSYSTEM表(可以简单记住system表),主要用到数据为标红区数据

第二张表INDICATION表(可以简单记住indication表),主要用到数据为标红区数据

第三张表INDICATIONVALUE表(可以简单记住value表),主要用到数据为标红区数据

三张表的对应关系为:

传入参数为system表中PID值,system表中ID对应indication表中INDICATIONSYSTEMIDS字段,查询indication表中ID,对应value表中INDICATIONID字段

实体层文件

Indiactionsystem.java

package zbinfo.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.mybatis.spring.annotation.MapperScan;

import java.io.Serializable;
import java.util.List;

@MapperScan
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Indicationsystem implements Serializable {

    @JsonProperty("id")
    private Long ID;

    @JsonProperty("name")
    private String NAME;

    @JsonProperty("pid")
    private Long PID;

    @JsonProperty("description")
    private String DESCRIPTION;

    @JsonProperty("children")
    private List<Indication> INDICATION;

    private static final long serialVersionUID = 1L;
    @JsonIgnore
    public Long getID() {
        return ID;
    }
    @JsonIgnore
    public void setID(Long ID) {
        this.ID = ID;
    }
    @JsonIgnore
    public String getNAME() {
        return NAME;
    }
    @JsonIgnore
    public void setNAME(String NAME) {
        this.NAME = NAME == null ? null : NAME.trim();
    }
    @JsonIgnore
    public Long getPID() {
        return PID;
    }
    @JsonIgnore
    public void setPID(Long PID) {
        this.PID = PID;
    }
    @JsonIgnore
    public String getDESCRIPTION() {
        return DESCRIPTION;
    }
    @JsonIgnore
    public void setDESCRIPTION(String DESCRIPTION) {
        this.DESCRIPTION = DESCRIPTION == null ? null : DESCRIPTION.trim();
    }
    @JsonIgnore
    public List<Indication> getINDICATION() {
        return INDICATION;
    }
    @JsonIgnore
    public void setINDICATION(List<Indication> INDICATION) {
        this.INDICATION = INDICATION;
    }
}

Indication.java

package zbinfo.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.mybatis.spring.annotation.MapperScan;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

@MapperScan
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Indication implements Serializable {

    @JsonProperty("id")
    private Long ID;

    @JsonProperty("name")
    private String NAME;

    @JsonProperty("range")
    private String RANGE;

    @JsonProperty("cycle")
    private String CYCLE;

    @JsonProperty("category")
    private String CATEGORY;

    @JsonProperty("source")
    private String SOURCE;

    @JsonProperty("dimention")
    private Long DIMENTION;

    @JsonProperty("indicationsystemids")
    private int[] INDICATIONSYSTEMIDS;

    @JsonProperty("patternids")
    private int[] PATTERNIDS;

    @JsonProperty("correlation")
    private String CORRELATION;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonProperty("limit")
    private String LIMIT;

    @JsonProperty("creationtime")
    private Date CREATIONTIME;

    @JsonProperty("areas")
    private List<Indicationvalue> INDICATIONVALUE;

    @JsonProperty("meaning")
    private String MEANING;

    @JsonProperty("organization")
    private String ORGANIZATION;



    private static final long serialVersionUID = 1L;

    @JsonIgnore
    public Long getID() {
        return ID;
    }
    @JsonIgnore
    public void setID(Long ID) {
        this.ID = ID;
    }
    @JsonIgnore
    public String getNAME() {
        return NAME;
    }
    @JsonIgnore
    public void setNAME(String NAME) {
        this.NAME = NAME == null ? null : NAME.trim();
    }
    @JsonIgnore
    public String getRANGE() {
        return RANGE;
    }
    @JsonIgnore
    public void setRANGE(String RANGE) {
        this.RANGE = RANGE == null ? null : RANGE.trim();
    }
    @JsonIgnore
    public String getCYCLE() {
        return CYCLE;
    }
    @JsonIgnore
    public void setCYCLE(String CYCLE) {
        this.CYCLE = CYCLE == null ? null : CYCLE.trim();
    }
    @JsonIgnore
    public String getCATEGORY() {
        return CATEGORY;
    }
    @JsonIgnore
    public void setCATEGORY(String CATEGORY) {
        this.CATEGORY = CATEGORY == null ? null : CATEGORY.trim();
    }
    @JsonIgnore
    public String getSOURCE() {
        return SOURCE;
    }
    @JsonIgnore
    public void setSOURCE(String SOURCE) {
        this.SOURCE = SOURCE == null ? null : SOURCE.trim();
    }
    @JsonIgnore
    public Long getDIMENTION() {
        return DIMENTION;
    }
    @JsonIgnore
    public void setDIMENTION(Long DIMENTION) {
        this.DIMENTION = DIMENTION;
    }
    @JsonIgnore
    public int[] getINDICATIONSYSTEMIDS() {
        return INDICATIONSYSTEMIDS;
    }
    @JsonIgnore
    public void setINDICATIONSYSTEMIDS(int[] INDICATIONSYSTEMIDS) {
        this.INDICATIONSYSTEMIDS = INDICATIONSYSTEMIDS == null ? null : INDICATIONSYSTEMIDS;
    }
    @JsonIgnore
    public int[] getPATTERNIDS() {
        return PATTERNIDS;
    }
    @JsonIgnore
    public void setPATTERNIDS(int[] PATTERNIDS) {
        this.PATTERNIDS = PATTERNIDS == null ? null : PATTERNIDS;
    }
    @JsonIgnore
    public String getCORRELATION() {
        return CORRELATION;
    }
    @JsonIgnore
    public void setCORRELATION(String CORRELATION) {
        this.CORRELATION = CORRELATION == null ? null : CORRELATION.trim();
    }
    @JsonIgnore
    public String getLIMIT() {
        return LIMIT;
    }
    @JsonIgnore
    public void setLIMIT(String LIMIT) {
        this.LIMIT = LIMIT == null ? null : LIMIT.trim();
    }
    @JsonIgnore
    public Date getCREATIONTIME() {
        return CREATIONTIME;
    }
    @JsonIgnore
    public void setCREATIONTIME(Date CREATIONTIME) {
        this.CREATIONTIME = CREATIONTIME;
    }
    @JsonIgnore
    public List<Indicationvalue> getINDICATIONVALUE() {
        return INDICATIONVALUE;
    }
    @JsonIgnore
    public void setINDICATIONVALUE(List<Indicationvalue> INDICATIONVALUE) {
        this.INDICATIONVALUE = INDICATIONVALUE;
    }
    @JsonIgnore
    public String getMEANING() {
        return MEANING;
    }
    @JsonIgnore
    public void setMEANING(String MEANING) {
        this.MEANING = MEANING;
    }
    @JsonIgnore
    public String getORGANIZATION() {
        return ORGANIZATION;
    }
    @JsonIgnore
    public void setORGANIZATION(String ORGANIZATION) {
        this.ORGANIZATION = ORGANIZATION;
    }
}

Indicationvalue.java

package zbinfo.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.mybatis.spring.annotation.MapperScan;

import java.io.Serializable;
import java.math.BigDecimal;

@MapperScan
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Indicationvalue implements Serializable {

    @JsonProperty("id")
    private Long ID;

    @JsonProperty("indicationid")
    private Long INDICATIONID;

    @JsonProperty("year")
    private Long YEAR;

    @JsonProperty("areacode")
    private String AREACODE;

    @JsonProperty("areaname")
    private String AREANAME;

    @JsonProperty("targetvalue")
    private String TARGETVALUE;

    @JsonProperty("actuallyvalue")
    private String ACTUALLYVALUE;

    @JsonProperty("unit")
    private String UNIT;

    @JsonProperty("threshold")
    private BigDecimal THRESHOLD;

    @JsonProperty("floatvalue")
    private BigDecimal FLOATVALUE;

    @JsonProperty("warningcolor")
    private String WARNINGCOLOR;

    @JsonProperty("weight")
    private BigDecimal WEIGHT;

    @JsonProperty("map_url")
    private String URL;

    @JsonProperty("sumActuallyValue")
    private Long SUMACTUALLY;

    @JsonProperty("sumTargetValue")
    private Long SUMTARGET;

    private static final long serialVersionUID = 1L;

    @JsonIgnore
    public Long getID() {
        return ID;
    }
    @JsonIgnore
    public void setID(Long ID) {
        this.ID = ID;
    }
    @JsonIgnore
    public Long getINDICATIONID() {
        return INDICATIONID;
    }
    @JsonIgnore
    public void setINDICATIONID(Long INDICATIONID) {
        this.INDICATIONID = INDICATIONID;
    }
    @JsonIgnore
    public Long getYEAR() {
        return YEAR;
    }
    @JsonIgnore
    public void setYEAR(Long YEAR) {
        this.YEAR = YEAR;
    }
    @JsonIgnore
    public String getAREACODE() {
        return AREACODE;
    }
    @JsonIgnore
    public void setAREACODE(String AREACODE) {
        this.AREACODE = AREACODE == null ? null : AREACODE.trim();
    }
    @JsonIgnore
    public String getAREANAME() {
        return AREANAME;
    }
    @JsonIgnore
    public void setAREANAME(String AREANAME) {
        this.AREANAME = AREANAME == null ? null : AREANAME.trim();
    }
    @JsonIgnore
    public String getTARGETVALUE() {
        return TARGETVALUE;
    }
    @JsonIgnore
    public void setTARGETVALUE(String TARGETVALUE) {
        this.TARGETVALUE = TARGETVALUE;
    }
    @JsonIgnore
    public String getACTUALLYVALUE() {
        return ACTUALLYVALUE;
    }
    @JsonIgnore
    public void setACTUALLYVALUE(String ACTUALLYVALUE) {
        this.ACTUALLYVALUE = ACTUALLYVALUE;
    }
    @JsonIgnore
    public String getUNIT() {
        return UNIT;
    }
    @JsonIgnore
    public void setUNIT(String UNIT) {
        this.UNIT = UNIT == null ? null : UNIT.trim();
    }
    @JsonIgnore
    public BigDecimal getTHRESHOLD() {
        return THRESHOLD;
    }
    @JsonIgnore
    public void setTHRESHOLD(BigDecimal THRESHOLD) {
        this.THRESHOLD = THRESHOLD;
    }
    @JsonIgnore
    public BigDecimal getFLOATVALUE() {
        return FLOATVALUE;
    }
    @JsonIgnore
    public void setFLOATVALUE(BigDecimal FLOATVALUE) {
        this.FLOATVALUE = FLOATVALUE;
    }
    @JsonIgnore
    public String getWARNINGCOLOR() {
        return WARNINGCOLOR;
    }
    @JsonIgnore
    public void setWARNINGCOLOR(String WARNINGCOLOR) {
        this.WARNINGCOLOR = WARNINGCOLOR == null ? null : WARNINGCOLOR.trim();
    }
    @JsonIgnore
    public BigDecimal getWEIGHT() {
        return WEIGHT;
    }
    @JsonIgnore
    public void setWEIGHT(BigDecimal WEIGHT) {
        this.WEIGHT = WEIGHT;
    }
    @JsonIgnore
    public String getURL() {
        return URL;
    }
    @JsonIgnore
    public void setURL(String URL) {
        this.URL = URL;
    }
    @JsonIgnore
    public Long getSUMACTUALLY() {
        return SUMACTUALLY;
    }
    @JsonIgnore
    public void setSUMACTUALLY(Long SUMACTUALLY) {
        this.SUMACTUALLY = SUMACTUALLY;
    }
    @JsonIgnore
    public Long getSUMTARGET() {
        return SUMTARGET;
    }
    @JsonIgnore
    public void setSUMTARGET(Long SUMTARGET) {
        this.SUMTARGET = SUMTARGET;
    }
}

其中

@JsonInclude(JsonInclude.Include.NON_NULL)

作用为搜索中无搜索字段,搜索结果对该字段返回null,去除这些结果为null的字段

@JsonProperty("areaname")

作用为返回结果中显示{字段:值},其中字段的显示名称

IndicationOverview.java实体层

本文因为项目中多次用到指标总览查询,故新建了IndicationOverview.java文件,该文件可以整合到Indicationsystem.java实体层文件中

package zbinfo.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.mybatis.spring.annotation.MapperScan;

import java.util.List;

/**
 * @program: ZBSERVICE
 * @description: 多级监测数据查询,如自然资源本底-耕地-耕地现状-耕地现状面积
 * @author: Mr.Li
 * @create: 2019-08-19
 **/

@MapperScan
public class IndicationOverview {
    @JsonProperty("id")
    private int ID;

    @JsonProperty("name")
    private String NAME;

    @JsonProperty("pid")
    private int PID;

    @JsonProperty("areaname")
    private String AREANAME;

    @JsonProperty("year")
    private int YEAR;

    @JsonProperty("warningcolor")
    private String WARNINGCOLOR;

    @JsonProperty("children")
    private List<Indication> INDICATION;

    @JsonProperty
    private List<IndicationOverview> INDICATIONOVERVIEW;

    @JsonIgnore
    public int getID() {
        return ID;
    }
    @JsonIgnore
    public void setID(int ID) {
        this.ID = ID;
    }
    @JsonIgnore
    public String getNAME() {
        return NAME;
    }
    @JsonIgnore
    public void setNAME(String NAME) {
        this.NAME = NAME;
    }
    @JsonIgnore
    public int getPID() {
        return PID;
    }
    @JsonIgnore
    public void setPID(int PID) {
        this.PID = PID;
    }
    @JsonIgnore
    public String getAREANAME() {
        return AREANAME;
    }
    @JsonIgnore
    public void setAREANAME(String AREANAME) {
        this.AREANAME = AREANAME;
    }
    @JsonIgnore
    public int getYEAR() {
        return YEAR;
    }
    @JsonIgnore
    public void setYEAR(int YEAR) {
        this.YEAR = YEAR;
    }
    @JsonIgnore
    public String getWARNINGCOLOR() {
        return WARNINGCOLOR;
    }
    @JsonIgnore
    public void setWARNINGCOLOR(String WARNINGCOLOR) {
        this.WARNINGCOLOR = WARNINGCOLOR;
    }

    @JsonIgnore
    public List<Indication> getINDICATION() {
        return INDICATION;
    }
    @JsonIgnore
    public void setINDICATION(List<Indication> INDICATION_OVERVIEW) {
        this.INDICATION = INDICATION_OVERVIEW;
    }
    @JsonIgnore
    public List<IndicationOverview> getINDICATIONOVERVIEW() {
        return INDICATIONOVERVIEW;
    }
    @JsonIgnore
    public void setINDICATIONOVERVIEW(List<IndicationOverview> INDICATIONOVERVIEW) {
        this.INDICATIONOVERVIEW = INDICATIONOVERVIEW;
    }
}

mapper文件三种写法

mapper文件(第一种写法)

IndicationsystemMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="zbinfo.dao.IndicationOverviewMapper">
    <resultMap id="BaseResultMap" type="java.util.HashMap">
        <id column="INDICATIONVALUEID" property="INDICATIONVALUEID" jdbcType="INTEGER"/>
        <result column="INDICATIONIDS" property="INDICATIONIDS" jdbcType="INTEGER"/>
        <result column="SYSTEMID" property="SYSTEMID" jdbcType="INTEGER"/>
        <result column="INDICATIONSYSTEMNAME" property="INDICATIONSYSTEMNAME" jdbcType="NVARCHAR"/>
        <result column="PID" property="PID" jdbcType="INTEGER"/>
        <collection  column="INDICATION" property="INDICATION" ofType="java.util.HashMap">
            <id column="INDICATIONIDS" property="INDICATIONIDS" jdbcType="INTEGER"/>
            <result column="INDICATIONNAME" property="INDICATIONNAME"  jdbcType="NVARCHAR"/>
            <result column="CYCLE" property="CYCLE"  jdbcType="NVARCHAR"/>
            <result column="SOURCE" property="SOURCE"  jdbcType="NVARCHAR"/>
            <collection column="INDICATIONVALUE" property="INDICATIONVALUE" ofType="java.util.HashMap">
                <id column="INDICATIONVALUEID" property="INDICATIONVALUEID" jdbcType="INTEGER"/>
                <result column="INDICATIONID" property="INDICATIONID"  jdbcType="OTHER"/>
                <result column="YEAR" property="YEAR"  jdbcType="NVARCHAR"/>
                <result column="AREANAME" property="AREANAME"  jdbcType="NVARCHAR"/>
                <result column="ACTUALLYVALUE" property="ACTUALLYVALUE"  jdbcType="NVARCHAR"/>
                <result column="UNIT" property="UNIT"  jdbcType="NVARCHAR"/>
            </collection>
        </collection>
    </resultMap>

    <select id="SelectByPID" resultMap="BaseResultMap">
        select a.ID as SYSTEMID,a.NAME as INDICATIONSYSTEMNAME,a.PID,d.INDICATIONIDS,d.INDICATIONNAME,d.CYCLE,d.SOURCE,d.INDICATIONVALUEID,d.INDICATIONID,d.YEAR,d.AREANAME,d.ACTUALLYVALUE,d.UNIT
        from indicationsystem a
        left join (select b.ID as INDICATIONIDS,b.NAME as INDICATIONNAME,b.CYCLE,b.SOURCE,b.INDICATIONSYSTEMIDS,c.ID AS INDICATIONVALUEID,c.INDICATIONID,c.YEAR,c.AREANAME,c.ACTUALLYVALUE,c.UNIT
                    from indication b
                    left join indicationvalue c
                      on b.ID = c.INDICATIONID) d
        on instr(d.INDICATIONSYSTEMIDS, to_char(a.ID)) > 0
        where a.PID = #{PID,jdbcType=INTEGER}
    </select>
</mapper>

其中

类型均为java.util.HashMap

这么写的好处是在resultmap中写了哪些字段,结果输出时只输出哪些字段(即使实体层中没有@JsonInclude(JsonInclude.Include.NON_NULL)注解,也是只输出这些字段)

注意:<collection>中property属性必须在实体层有对应的字段,及getter和setter方法

该种写法中,sql语句采用一次查询,一次访问数据库的写法

sql语句中避免各表字段重复,将需要查询字段使用as重新定义字段

接口文件

IndicationsystemMapper.java

package zbinfo.dao;

import org.apache.ibatis.annotations.Mapper;
import zbinfo.model.IndicationOverview;

import java.util.List;

@Mapper
public interface IndicationOverviewMapper {
    /*通过PID查询,从第三级指标开始查询*/
    List<IndicationOverview> SelectByPID(Object jsonObject);
}

Controller文件

IndicationOverviewController.java

package zbinfo.controller;

import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import zbinfo.dao.IndicationOverviewMapper;
import zbinfo.model.Indication;
import zbinfo.model.IndicationOverview;
import zbinfo.model.Indicationvalue;

import java.util.List;

/**
 * @program: ZBSERVICE
 * @description: 各个指标监测数据展示
 * @author: Mr.Li
 * @create: 2019-08-20
 **/
@RestController
@RequestMapping(value="IndicationOverview")
public class IndicationOverviewController {
    @Autowired
    IndicationOverviewMapper overViewMapper;

    private static final Logger logger = LoggerFactory.getLogger(IndicationOverviewController.class);

    @RequestMapping(value="/SelectByPID",method= RequestMethod.POST)
    public List<IndicationOverview> SelectByPID(
         //@PathVariable(name = "PID", required = true) Integer PID
         @RequestBody JSONObject jsonObject
    ){
        logger.debug("开始进行指标总览查询");
        logger.debug("查询方法:SelectIndicationOverview,参数:jsonObject=%S",jsonObject);
        try
        {
            List<IndicationOverview> lstOverview = overViewMapper.SelectByPID(jsonObject);
            logger.debug("指标总览查询结束,查询成功");
            return lstOverview;
        }
        catch (Exception e)
        {
            logger.error(e.getMessage());
            logger.debug("指标总览查询操作结束,查询失败");
            return null;
        }
    }
}

如果没有配置日志文件,可以将logger相关的语句注释掉;

也可以将try{}catch(){}语句注释掉

package zbinfo.controller;

import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import zbinfo.dao.IndicationOverviewMapper;
import zbinfo.model.IndicationOverview;

import java.util.List;

/**
 * @program: ZBSERVICE
 * @description: 各个指标监测数据展示
 * @author: Mr.Li
 * @create: 2019-08-20
 **/
@RestController
@RequestMapping(value="IndicationOverview")
public class IndicationOverviewController {
    @Autowired
    IndicationOverviewMapper overViewMapper;

    @RequestMapping(value="/SelectByPID",method= RequestMethod.POST)
    public List<IndicationOverview> SelectByPID(
         //@PathVariable(name = "PID", required = true) Integer PID
         @RequestBody JSONObject jsonObject
    ){
        
            List<IndicationOverview> lstOverview = overViewMapper.SelectByPID(jsonObject);
            return lstOverview;
    }
}

在postman中调试

结果:

由于结果类型使用java.util.HashMap,没有引用实体层文件,实体层@JsonProperty注解没有起作用(请看下面注意

最终结果直接将sql语句搜索结果匹配mapresult中规定字段;

[
    {
        "INDICATIONIDS": 1,
        "SYSTEMID": 23,
        "PID": 9,
        "INDICATIONSYSTEMNAME": "耕地现状",
        "INDICATIONVALUEID": 1,
        "INDICATION": {
            "INDICATIONIDS": 1,
            "INDICATIONVALUE": {
                "UNIT": "公顷",
                "YEAR": 2010,
                "INDICATIONID": 1,
                "AREANAME": "福田区",
                "ACTUALLYVALUE": "12345",
                "INDICATIONVALUEID": 1
            },
            "INDICATIONNAME": "耕地现状面积",
            "SOURCE": "填报",
            "CYCLE": "10年"
        }
    },
    {
        "INDICATIONIDS": 1,
        "SYSTEMID": 23,
        "PID": 9,
        "INDICATIONSYSTEMNAME": "耕地现状",
        "INDICATIONVALUEID": 2,
        "INDICATION": {
            "INDICATIONIDS": 1,
            "INDICATIONVALUE": {
                "UNIT": "公顷",
                "YEAR": 2011,
                "INDICATIONID": 1,
                "AREANAME": "福田区",
                "ACTUALLYVALUE": "12345",
                "INDICATIONVALUEID": 2
            },
            "INDICATIONNAME": "耕地现状面积",
            "SOURCE": "填报",
            "CYCLE": "10年"
        }
    },
    {
        "INDICATIONIDS": 1,
        "SYSTEMID": 23,
        "PID": 9,
        "INDICATIONSYSTEMNAME": "耕地现状",
        "INDICATIONVALUEID": 23,
        "INDICATION": {
            "INDICATIONIDS": 1,
            "INDICATIONVALUE": {
                "UNIT": "公顷",
                "YEAR": 2010,
                "INDICATIONID": 1,
                "AREANAME": "南山区",
                "ACTUALLYVALUE": "123456",
                "INDICATIONVALUEID": 23
            },
            "INDICATIONNAME": "耕地现状面积",
            "SOURCE": "填报",
            "CYCLE": "10年"
        }
    },
    {
        "INDICATIONIDS": 4,
        "SYSTEMID": 23,
        "PID": 9,
        "INDICATIONSYSTEMNAME": "耕地现状",
        "INDICATIONVALUEID": 24,
        "INDICATION": {
            "INDICATIONIDS": 4,
            "INDICATIONVALUE": {
                "UNIT": "等别",
                "YEAR": 2010,
                "INDICATIONID": 4,
                "AREANAME": "福田区",
                "ACTUALLYVALUE": "一等",
                "INDICATIONVALUEID": 24
            },
            "INDICATIONNAME": "耕地质量",
            "SOURCE": "填报",
            "CYCLE": "10年"
        }
    },
    {
        "INDICATIONIDS": 4,
        "SYSTEMID": 23,
        "PID": 9,
        "INDICATIONSYSTEMNAME": "耕地现状",
        "INDICATIONVALUEID": 25,
        "INDICATION": {
            "INDICATIONIDS": 4,
            "INDICATIONVALUE": {
                "UNIT": "等别",
                "YEAR": 2011,
                "INDICATIONID": 4,
                "AREANAME": "福田区",
                "ACTUALLYVALUE": "二等",
                "INDICATIONVALUEID": 25
            },
            "INDICATIONNAME": "耕地质量",
            "SOURCE": "填报",
            "CYCLE": "10年"
        }
    },
    {
        "INDICATIONIDS": 4,
        "SYSTEMID": 23,
        "PID": 9,
        "INDICATIONSYSTEMNAME": "耕地现状",
        "INDICATIONVALUEID": 26,
        "INDICATION": {
            "INDICATIONIDS": 4,
            "INDICATIONVALUE": {
                "UNIT": "等别",
                "YEAR": 2010,
                "INDICATIONID": 4,
                "AREANAME": "南山区",
                "ACTUALLYVALUE": "一等",
                "INDICATIONVALUEID": 26
            },
            "INDICATIONNAME": "耕地质量",
            "SOURCE": "填报",
            "CYCLE": "10年"
        }
    },
    {
        "INDICATIONIDS": 2,
        "SYSTEMID": 23,
        "PID": 9,
        "INDICATIONSYSTEMNAME": "耕地现状",
        "INDICATION": {
            "INDICATIONIDS": 2,
            "INDICATIONNAME": "破碎度",
            "SOURCE": "填报",
            "CYCLE": "10年"
        }
    },
    {
        "INDICATIONIDS": 3,
        "SYSTEMID": 23,
        "PID": 9,
        "INDICATIONSYSTEMNAME": "耕地现状",
        "INDICATION": {
            "INDICATIONIDS": 3,
            "INDICATIONNAME": "建设用地占用耕地数量",
            "SOURCE": "填报",
            "CYCLE": "10年"
        }
    },
    {
        "INDICATIONIDS": 22,
        "SYSTEMID": 24,
        "PID": 9,
        "INDICATIONSYSTEMNAME": "永久基本农田",
        "INDICATIONVALUEID": 27,
        "INDICATION": {
            "INDICATIONIDS": 22,
            "INDICATIONVALUE": {
                "UNIT": "公顷",
                "YEAR": 2010,
                "INDICATIONID": 22,
                "AREANAME": "福田区",
                "ACTUALLYVALUE": "12345",
                "INDICATIONVALUEID": 27
            },
            "INDICATIONNAME": "永久基本农田面积",
            "SOURCE": "一张图",
            "CYCLE": "10年"
        }
    },
    {
        "INDICATIONIDS": 22,
        "SYSTEMID": 24,
        "PID": 9,
        "INDICATIONSYSTEMNAME": "永久基本农田",
        "INDICATIONVALUEID": 28,
        "INDICATION": {
            "INDICATIONIDS": 22,
            "INDICATIONVALUE": {
                "UNIT": "公顷",
                "YEAR": 2011,
                "INDICATIONID": 22,
                "AREANAME": "福田区",
                "ACTUALLYVALUE": "123456",
                "INDICATIONVALUEID": 28
            },
            "INDICATIONNAME": "永久基本农田面积",
            "SOURCE": "一张图",
            "CYCLE": "10年"
        }
    },
    {
        "INDICATIONIDS": 22,
        "SYSTEMID": 24,
        "PID": 9,
        "INDICATIONSYSTEMNAME": "永久基本农田",
        "INDICATIONVALUEID": 29,
        "INDICATION": {
            "INDICATIONIDS": 22,
            "INDICATIONVALUE": {
                "UNIT": "公顷",
                "YEAR": 2010,
                "INDICATIONID": 22,
                "AREANAME": "南山区",
                "ACTUALLYVALUE": "1234",
                "INDICATIONVALUEID": 29
            },
            "INDICATIONNAME": "永久基本农田面积",
            "SOURCE": "一张图",
            "CYCLE": "10年"
        }
    },
    {
        "SYSTEMID": 25,
        "PID": 9,
        "INDICATIONSYSTEMNAME": "高标准农田"
    }
]

这种写法中返回的数据是一条数据一条数据返回的,即json没有任何合并现象

注意:

在写<collection>标签和sql语句时,注意返回数据的顺序,system中ID少,indication中ID多一点,value中ID最多,如果顺序有问题,以system结果输出,最终输出的结果,只能是system中ID数为最终数据的条数,

应该以value表中数据ID输出,这样是正确的数据条数。

解决方法,在resultmap中的<collection>标签中将几个ID进行区分,所以本文用sql语句中使用as将ID进行区分,并修改了<collection>中的属性

 

mapper文件(第二种写法)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="zbinfo.dao.IndicationOverviewMapper">
    <resultMap id="BaseResultMap" type="zbinfo.model.IndicationOverview">
        <!--<id column="INDICATIONVALUEID" property="ID" jdbcType="INTEGER"/>-->
        <result column="INDICATIONSYSTEMNAME" property="NAME" jdbcType="NVARCHAR"/>
        <result column="PID" property="PID" jdbcType="INTEGER"/>
        <collection  column="INDICATION" property="INDICATION" ofType="zbinfo.model.Indication">
            <id column="INDICATIONIDS" property="ID" jdbcType="INTEGER"/>
            <result column="INDICATIONNAME" property="NAME"  jdbcType="NVARCHAR"/>
            <result column="CYCLE" property="CYCLE"  jdbcType="NVARCHAR"/>
            <result column="SOURCE" property="SOURCE"  jdbcType="NVARCHAR"/>
            <collection column="INDICATIONVALUE" property="INDICATIONVALUE" ofType="zbinfo.model.Indicationvalue">
                <id column="INDICATIONVALUEID" property="ID" jdbcType="INTEGER"/>
                <result column="INDICATIONID" property="INDICATIONID"  jdbcType="OTHER"/>
                <result column="YEAR" property="YEAR"  jdbcType="NVARCHAR"/>
                <result column="AREANAME" property="AREANAME"  jdbcType="NVARCHAR"/>
                <result column="ACTUALLYVALUE" property="ACTUALLYVALUE"  jdbcType="NVARCHAR"/>
                <result column="UNIT" property="UNIT"  jdbcType="NVARCHAR"/>
            </collection>
        </collection>
        <!--</collection>-->
    </resultMap>

    <select id="SelectByPID" resultMap="BaseResultMap">
        select a.ID as SYSTEMID,a.NAME as INDICATIONSYSTEMNAME,a.PID,d.INDICATIONIDS,d.INDICATIONNAME,d.CYCLE,d.SOURCE,d.INDICATIONVALUEID,d.INDICATIONID,d.YEAR,d.AREANAME,d.ACTUALLYVALUE,d.UNIT
        from indicationsystem a
        left join (select b.ID as INDICATIONIDS,b.NAME as INDICATIONNAME,b.CYCLE,b.SOURCE,b.INDICATIONSYSTEMIDS,c.ID AS INDICATIONVALUEID,c.INDICATIONID,c.YEAR,c.AREANAME,c.ACTUALLYVALUE,c.UNIT
                    from indication b
                    left join indicationvalue c
                      on b.ID = c.INDICATIONID) d
        on instr(d.INDICATIONSYSTEMIDS, to_char(a.ID)) > 0
        where a.PID = #{PID,jdbcType=INTEGER}
    </select>
</mapper>

其中

将type修改成为各实体层文件

这样实体层中的注解

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonProperty("id")

将会起作用;

这样写的好处,就是上层重复的数据在json文件中将合并,即system表中数据相同ID合并,indication表相同ID数据合并

结果:

[
    {
        "INDICATIONOVERVIEW": null,
        "id": 0,
        "name": "耕地现状",
        "pid": 9,
        "areaname": null,
        "year": 0,
        "warningcolor": null,
        "children": [
            {
                "id": 1,
                "name": "耕地现状面积",
                "cycle": "10年",
                "source": "填报",
                "areas": [
                    {
                        "id": 1,
                        "indicationid": 1,
                        "year": 2010,
                        "areaname": "福田区",
                        "actuallyvalue": "12345",
                        "unit": "公顷"
                    },
                    {
                        "id": 2,
                        "indicationid": 1,
                        "year": 2011,
                        "areaname": "福田区",
                        "actuallyvalue": "12345",
                        "unit": "公顷"
                    },
                    {
                        "id": 23,
                        "indicationid": 1,
                        "year": 2010,
                        "areaname": "南山区",
                        "actuallyvalue": "123456",
                        "unit": "公顷"
                    }
                ]
            },
            {
                "id": 4,
                "name": "耕地质量",
                "cycle": "10年",
                "source": "填报",
                "areas": [
                    {
                        "id": 24,
                        "indicationid": 4,
                        "year": 2010,
                        "areaname": "福田区",
                        "actuallyvalue": "一等",
                        "unit": "等别"
                    },
                    {
                        "id": 25,
                        "indicationid": 4,
                        "year": 2011,
                        "areaname": "福田区",
                        "actuallyvalue": "二等",
                        "unit": "等别"
                    },
                    {
                        "id": 26,
                        "indicationid": 4,
                        "year": 2010,
                        "areaname": "南山区",
                        "actuallyvalue": "一等",
                        "unit": "等别"
                    }
                ]
            },
            {
                "id": 41,
                "name": "耕地保有量",
                "cycle": "110年",
                "source": "填报",
                "areas": []
            },
            {
                "id": 2,
                "name": "破碎度",
                "cycle": "10年",
                "source": "填报",
                "areas": []
            },
            {
                "id": 3,
                "name": "建设用地占用耕地数量",
                "cycle": "10年",
                "source": "填报",
                "areas": []
            }
        ]
    },
    {
        "INDICATIONOVERVIEW": null,
        "id": 0,
        "name": "永久基本农田",
        "pid": 9,
        "areaname": null,
        "year": 0,
        "warningcolor": null,
        "children": [
            {
                "id": 22,
                "name": "永久基本农田面积",
                "cycle": "10年",
                "source": "一张图",
                "areas": [
                    {
                        "id": 27,
                        "indicationid": 22,
                        "year": 2010,
                        "areaname": "福田区",
                        "actuallyvalue": "12345",
                        "unit": "公顷"
                    },
                    {
                        "id": 28,
                        "indicationid": 22,
                        "year": 2011,
                        "areaname": "福田区",
                        "actuallyvalue": "123456",
                        "unit": "公顷"
                    },
                    {
                        "id": 29,
                        "indicationid": 22,
                        "year": 2010,
                        "areaname": "南山区",
                        "actuallyvalue": "1234",
                        "unit": "公顷"
                    }
                ]
            }
        ]
    },
    {
        "INDICATIONOVERVIEW": null,
        "id": 0,
        "name": "高标准农田",
        "pid": 9,
        "areaname": null,
        "year": 0,
        "warningcolor": null,
        "children": []
    }
]

mapper文件(第三种写法)

sql语句分开写,<collection>只嵌套一层

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="zbinfo.dao.IndicationOverviewMapper">

    <resultMap id="BaseResultMap" type="zbinfo.model.IndicationOverview">
        <!--<id column="INDICATIONVALUEID" property="ID" jdbcType="INTEGER"/>-->
        <result column="INDICATIONSYSTEMNAME" property="NAME" jdbcType="NVARCHAR"/>
        <result column="PID" property="PID" jdbcType="INTEGER"/>
        <result column="INDICATIONSYSTEMID" property="ID" jdbcType="INTEGER"/>
        <collection property="INDICATION" select="SelectBySystemID" column="{systemID=INDICATIONSYSTEMID,AREANAME=AREANAME,YEAR=YEAR,WARNINGCOLOR=WARNINGCOLOR}">

        </collection>
    </resultMap>
    <resultMap id="BaseResultMap1" type="zbinfo.model.Indication">
        <id column="INDICATIONIDS" property="ID" jdbcType="INTEGER"/>
        <result column="INDICATIONNAME" property="NAME"  jdbcType="NVARCHAR"/>
        <result column="CYCLE" property="CYCLE"  jdbcType="NVARCHAR"/>
        <result column="SOURCE" property="SOURCE"  jdbcType="NVARCHAR"/>
        <result column="MEANING" property="MEANING" jdbcType="NVARCHAR"/>
        <result column="ORGANIZATION" property="ORGANIZATION" jdbcType="NVARCHAR"/>
        <collection property="INDICATIONVALUE" select="SelectByIndicationID" column="{indicaID=INDICATIONIDS,AREANAME=AREANAME,YEAR=YEAR,WARNINGCOLOR=WARNINGCOLOR}">

        </collection>
    </resultMap>
    <resultMap id="BaseResultMap2" type="zbinfo.model.Indicationvalue">
        <id column="INDICATIONVALUEID" property="ID" jdbcType="INTEGER"/>
        <result column="INDICATIONID" property="INDICATIONID"  jdbcType="OTHER"/>
        <result column="YEAR" property="YEAR"  jdbcType="NVARCHAR"/>
        <result column="AREANAME" property="AREANAME"  jdbcType="NVARCHAR"/>
        <result column="TARGETVALUE" property="TARGETVALUE" jdbcType="NVARCHAR"/>
        <result column="ACTUALLYVALUE" property="ACTUALLYVALUE"  jdbcType="NVARCHAR"/>
        <result column="UNIT" property="UNIT" jdbcType="NVARCHAR"/>
        <result column="URL" property="URL" jdbcType="NVARCHAR"/>
        <result column="THRESHOLD" property="THRESHOLD" jdbcType="DECIMAL"/>
        <result column="WARNINGCOLOR" property="WARNINGCOLOR" jdbcType="NVARCHAR"/>
    </resultMap>
    
    <select id="SelectByPID" resultMap="BaseResultMap" parameterType="java.lang.Integer">
        select a.ID as INDICATIONSYSTEMID,a.NAME as INDICATIONSYSTEMNAME,a.PID
        <if test="YEAR != null">
            ,#{YEAR,jdbcType=INTEGER} as YEAR
        </if>
        <if test="WARNINGCOLOR != null">
            ,#{WARNINGCOLOR,jdbcType=NVARCHAR} as WARNINGCOLOR
        </if>
        <if test="AREANAME != null">
            ,#{AREANAME,jdbcType=NVARCHAR} as AREANAME
        </if>
        from indicationsystem a
        where a.PID = #{PID,jdbcType=INTEGER}
    </select>
    <select id="SelectBySystemID" resultMap="BaseResultMap1" parameterType="java.util.Map">
        select ID as INDICATIONIDS,NAME as INDICATIONNAME,CYCLE,SOURCE,MEANING,ORGANIZATION
        <if test="YEAR != null">
            ,#{YEAR,jdbcType=INTEGER} as YEAR
        </if>
        <if test="WARNINGCOLOR != null">
            ,#{WARNINGCOLOR,jdbcType=NVARCHAR} as WARNINGCOLOR
        </if>
        <if test="AREANAME != null">
            ,#{AREANAME,jdbcType=NVARCHAR} as AREANAME
        </if>
        from INDICATION
        where instr(INDICATIONSYSTEMIDS, ','||#{systemID}||',') > 0
    </select>
    <select id="SelectByIndicationID" resultMap="BaseResultMap2" parameterType="java.util.Map">
        select ID as INDICATIONVALUEID,INDICATIONID,YEAR,AREANAME,TARGETVALUE,ACTUALLYVALUE,UNIT,THRESHOLD,WARNINGCOLOR
        from INDICATIONVALUE
        <where>
            INDICATIONID = #{indicaID}
            <if test="YEAR != null">
                and YEAR = #{YEAR,jdbcType=INTEGER}
            </if>
            <if test="WARNINGCOLOR != null">
                <if test="WARNINGCOLOR != '0'.toString()">
                    and WARNINGCOLOR = #{WARNINGCOLOR,jdbcType=NVARCHAR}
                </if>
            </if>
            <if test="AREANAME != null">
                <if test="AREANAME != '深圳市'.toString()">
                    AREANAME = #{AREANAME,jdbcType=NVARCHAR}
                </if>
            </if>
        </where>
    </select>
</mapper>

第一个resultmap,system表搜索字段,嵌套一个<collection>,该标签中不写搜索字段;

                         其中collection标签中的column属性为system表与indication表关联字段;

                        (本文中传入4个参数,后三个参数以常数项进行传入

第二个resultmap,indication表搜索字段,嵌套一个<collection>,该标签中不写搜索字段;

第三个resultmap,value表搜索字段;

一次类推,不管搜索多少个表都可以;

postman调试:

结果:

[
    {
        "INDICATIONOVERVIEW": null,
        "id": 23,
        "name": "耕地现状",
        "pid": 9,
        "areaname": "深圳市",
        "year": 2010,
        "warningcolor": "0",
        "children": [
            {
                "id": 1,
                "name": "耕地现状面积",
                "cycle": "10年",
                "source": "填报",
                "areas": [
                    {
                        "id": 1,
                        "indicationid": 1,
                        "year": 2010,
                        "areaname": "福田区",
                        "targetvalue": "12345",
                        "actuallyvalue": "12345",
                        "unit": "公顷",
                        "threshold": 0,
                        "warningcolor": "1(绿)"
                    },
                    {
                        "id": 23,
                        "indicationid": 1,
                        "year": 2010,
                        "areaname": "南山区",
                        "targetvalue": "123456",
                        "actuallyvalue": "123456",
                        "unit": "公顷"
                    }
                ],
                "meaning": "耕地现状面积",
                "organization": "耕地现状面积"
            },
            {
                "id": 4,
                "name": "耕地质量",
                "cycle": "10年",
                "source": "填报",
                "areas": [
                    {
                        "id": 24,
                        "indicationid": 4,
                        "year": 2010,
                        "areaname": "福田区",
                        "targetvalue": "一等",
                        "actuallyvalue": "一等",
                        "unit": "等别",
                        "threshold": -10,
                        "warningcolor": "3(红)"
                    },
                    {
                        "id": 26,
                        "indicationid": 4,
                        "year": 2010,
                        "areaname": "南山区",
                        "targetvalue": "一等",
                        "actuallyvalue": "一等",
                        "unit": "等别"
                    }
                ],
                "meaning": "耕地质量",
                "organization": "耕地质量"
            }
        ]
    },
    {
        "INDICATIONOVERVIEW": null,
        "id": 24,
        "name": "永久基本农田",
        "pid": 9,
        "areaname": "深圳市",
        "year": 2010,
        "warningcolor": "0",
        "children": [
            {
                "id": 22,
                "name": "永久基本农田面积",
                "cycle": "10年",
                "source": "一张图",
                "areas": [
                    {
                        "id": 27,
                        "indicationid": 22,
                        "year": 2010,
                        "areaname": "福田区",
                        "targetvalue": "12345",
                        "actuallyvalue": "12345",
                        "unit": "公顷"
                    },
                    {
                        "id": 29,
                        "indicationid": 22,
                        "year": 2010,
                        "areaname": "南山区",
                        "targetvalue": "1234",
                        "actuallyvalue": "1234",
                        "unit": "公顷"
                    }
                ]
            }
        ]
    },
    {
        "INDICATIONOVERVIEW": null,
        "id": 25,
        "name": "高标准农田",
        "pid": 9,
        "areaname": "深圳市",
        "year": 2010,
        "warningcolor": "0",
        "children": []
    }
]

 

  • 7
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值