MyBatis中嵌套的<collection>和<association>给出NULL作为结果

时间:2019-04-04 11:45:53

标签: java mybatis spring-mybatis

我有一个MyBatis映射器文件,看起来像这样-

<mapper namespace="ABCDEFGH">

  <resultMap id="userWiseData" type="UserWiseData">
    <id property="personId" column="person_id"/>

    <association
        property="mandatorySTC"
        javaType="TypeWiseData"
        resultSet="mandatorySTCResult">
      <id property="typeId" column="type_id"/>
      <result property="personId" column="person_id"/>

      <collection
          property="hrCompanyWiseData"
          ofType="HRCompanyWiseData">

        <id property="companyId" column="company_id"/>
        <result property="companyCode" column="company_code"/>

        <association
            property="nonMidYear"
            javaType="PeriodWiseData">

          <id property="periodId" column="non_mid_year_period_id"/>

          <collection
              property="investmentDateWiseData"
              ofType="InvestmentDateWiseData">

            <id property="investmentDateId" column="non_mid_year_investment_date_id"/>

            <collection
              property="vestingDateWiseData"
              ofType="VestingDateWiseData">

              <id property="vestingDateId" column="non_mid_year_vesting_date_id"/>
              <result property="awardDate" column="non_mid_year_award_date"/>
              <result property="investmentDate" column="non_mid_year_investment_date"/>
              <result property="vestingDate" column="non_mid_year_vesting_date"/>
              <result property="amount" column="non_mid_year_amount"/>
              <result property="returnAmount" column="non_mid_year_return_amount"/>
              <result property="vestingAmount" column="non_mid_year_vesting_amount"/>

            </collection>

          </collection>
        </association>

        <association
            property="midYear"
            javaType="PeriodWiseData">

          <id property="periodId" column="mid_year_period_id"/>

          <collection
              property="investmentDateWiseData"
              ofType="InvestmentDateWiseData">

            <id property="investmentDateId" column="mid_year_investment_date_id"/>

            <collection
                property="vestingDateWiseData"
                ofType="VestingDateWiseData">

              <id property="vestingDateId" column="mid_year_vesting_date_id"/>
              <result property="awardDate" column="mid_year_award_date"/>
              <result property="investmentDate" column="mid_year_investment_date"/>
              <result property="vestingDate" column="mid_year_vesting_date"/>
              <result property="amount" column="mid_year_amount"/>
              <result property="returnAmount" column="mid_year_return_amount"/>
              <result property="vestingAmount" column="mid_year_vesting_amount"/>

            </collection>

          </collection>
        </association>

      </collection>

    </association>
  </resultMap>

  <select id="fetchUserWiseData" resultSets="mandatorySTCResult"
      resultMap="userWiseData">

    select '3520' as person_id

    <!-- This gives results as shown in the CSV file below, which is - mandatorySTCResult -->
  </select>

</mapper>

这些是我试图将数据获取到的类-

public class UserWiseData {
    private String personId;
    private TypeWiseData mandatorySTC;

    // Setter-Getters
}

public class TypeWiseData {
    private String typeId;
    private String personId;
    private List<HRCompanyWiseData> hrCompanyWiseData;

    // Setter-Getters
}


public class HRCompanyWiseData {
    private String companyId;
    private String companyCode;
    private PeriodWiseData nonMidYear;
    private PeriodWiseData midYear;

    // Setter-Getters
}

public class PeriodWiseData {
    private String periodId;
    private List<InvestmentDateWiseData> investmentDateWiseData;

    // Setter-Getters
}

public class InvestmentDateWiseData {
    private String investmentDateId;
    private List<VestingDateWiseData> vestingDateWiseData;

    // Setter-Getters
}


public class VestingDateWiseData {
    private String vestingDateId;
    private String awardDate;
    private String investmentDate;
    private String vestingDate;
    private Double amount;
    private Double returnAmount;
    private Double vestingAmount;

    // Setter-Getters
}

查询结果看起来像这样-

person_id   type_id             company_id              company_code    non_mid_year_period_id                  non_mid_year_investment_date_id                 non_mid_year_vesting_date_id                                non_mid_year_award_date non_mid_year_investment_date    non_mid_year_vesting_date   non_mid_year_amount non_mid_year_return_amount  non_mid_year_vesting_amount mid_year_period_id  mid_year_investment_date_id mid_year_vesting_date_id    mid_year_award_date mid_year_investment_date    mid_year_vesting_date   mid_year_amount mid_year_return_amount  mid_year_vesting_amount
3520        3520-mandatory_stc  3520-mandatory_stc-EFGH EFGH            3520-mandatory_stc-EFGH-non_mid_year    3520-mandatory_stc-EFGH-non_mid_year-2018-01-01 3520-mandatory_stc-EFGH-non_mid_year-2018-01-01-2018-12-31  1/1/2018                1/1/2018                        12/31/2018                  16150               2374.05                     18524.05                                    
3520        3520-mandatory_stc  3520-mandatory_stc-ABCD ABCD            3520-mandatory_stc-ABCD-non_mid_year    3520-mandatory_stc-ABCD-non_mid_year-2018-01-01 3520-mandatory_stc-ABCD-non_mid_year-2018-01-01-2019-12-31  1/1/2018                1/1/2018                        12/31/2019                  6000                882                         6882                                    
3520        3520-mandatory_stc  3520-mandatory_stc-EFGH EFGH            3520-mandatory_stc-EFGH-non_mid_year    3520-mandatory_stc-EFGH-non_mid_year-2018-01-01 3520-mandatory_stc-EFGH-non_mid_year-2018-01-01-2019-12-31  1/1/2018                1/1/2018                        12/31/2019                  16150               2374.05                     18524.05                                    
3520        3520-mandatory_stc  3520-mandatory_stc-ABCD ABCD            3520-mandatory_stc-ABCD-non_mid_year    3520-mandatory_stc-ABCD-non_mid_year-2018-01-01 3520-mandatory_stc-ABCD-non_mid_year-2018-01-01-2020-12-31  1/1/2018                1/1/2018                        12/31/2020                  6000                882                         6882                                    
3520        3520-mandatory_stc  3520-mandatory_stc-EFGH EFGH            3520-mandatory_stc-EFGH-non_mid_year    3520-mandatory_stc-EFGH-non_mid_year-2018-01-01 3520-mandatory_stc-EFGH-non_mid_year-2018-01-01-2020-12-31  1/1/2018                1/1/2018                        12/31/2020                  16150               2374.05                     18524.05                                    

我用columnforeignColumn<association>尝试过 和<collection>标签。但它仍然给出相同的结果。


我希望我的结果看起来像这样-

{
  "userWiseData": [
    {
      "personId": "3520",
      "mandatorySTC": {
        "typeId": "3520-mandatory_stc",
        "personId": "3520",
        "hrCompanyWiseData": [
          {
            "companyId": "3520-mandatory_stc-ABCD",
            "companyCode": "ABCD",
            "monMidYear": {
              "periodId": "3520-mandatory_stc-ABCD-non_mid_year",
              "investmentDateWiseData": [
                {
                  "investmentDateId": "3520-mandatory_stc-ABCD-non_mid_year-2018-01-01",
                  "vestingDateWiseData": [
                    {
                      "vestingDateId": "3520-mandatory_stc-ABCD-non_mid_year-2018-01-01-2019-12-31",
                      "awardDate": "01/01/2018",
                      "investmentDate": "01/01/2018",
                      "vestingDate": "12/31/2019",
                      "amount": "6000",
                      "returnAmount": "882",
                      "vestingAmount": "6882"
                    },
                    {
                      "vestingDateId": "3520-mandatory_stc-ABCD-non_mid_year-2018-01-01-2020-12-31",
                      "awardDate": "01/01/2018",
                      "investmentDate": "01/01/2018",
                      "vestingDate": "12/31/2020",
                      "amount": "6000",
                      "returnAmount": "882",
                      "vestingAmount": "6882"
                    }
                  ]
                }
              ]
            },
            "midYear": {}
          },
          {
            "companyId": "3520-mandatory_stc-EFGH",
            "companyCode": "EFGH",
            "monMidYear": {
              "periodId": "3520-mandatory_stc-EFGH-non_mid_year",
              "investmentDateWiseData": [
                {
                  "investmentDateId": "3520-mandatory_stc-EFGH-non_mid_year-2018-01-01",
                  "vestingDateWiseData": [
                    {
                      "vestingDateId": "3520-mandatory_stc-EFGH-non_mid_year-2018-01-01-2018-12-31",
                      "awardDate": "01/01/2018",
                      "investmentDate": "01/01/2018",
                      "vestingDate": "12/31/2018",
                      "amount": "16150",
                      "returnAmount": "2374.05",
                      "vestingAmount": "18524.05"
                    },
                    {
                      "vestingDateId": "3520-mandatory_stc-EFGH-non_mid_year-2018-01-01-2019-12-31",
                      "awardDate": "01/01/2018",
                      "investmentDate": "01/01/2018",
                      "vestingDate": "12/31/2019",
                      "amount": "16150",
                      "returnAmount": "2374.05",
                      "vestingAmount": "18524.05"
                    },
                    {
                      "vestingDateId": "3520-mandatory_stc-EFGH-non_mid_year-2018-01-01-2020-12-31",
                      "awardDate": "01/01/2018",
                      "investmentDate": "01/01/2018",
                      "vestingDate": "12/31/2020",
                      "amount": "16150",
                      "returnAmount": "2374.05",
                      "vestingAmount": "18524.05"
                    }
                  ]
                }
              ]
            },
            "midYear": {}
          }
        ]
      }
    }
  ]
}

但是,我得到的是mandatorySTC的一个空值,就像这样-

{
  "userWiseData": [
    {
      "mandatorySTC": null,
      "personId": "3520"
    }
  ]
}

我正在使用-

<mybatis.version>3.5.0</mybatis.version>
<mybatis.spring.version>2.00</mybatis.spring.version>

我尝试使用resultSet的原因是我必须添加更多类似mandatorySTC的关联,并且我想重新使用在<select id="fetchUserWiseData">中创建的临时表来同时获取其他resultSets的数据。


如果我从查询中删除了resultSet="mandatorySTCResult"中的<association>和查询中的select '3520' as person_id,我将按预期获取数据。

2 个答案:

答案 0 :(得分:1)

我认为您误解了resultSet的含义。
这意味着java.sql.ResultSet,如果您在resultSet="mandatorySTCResult"中指定了<association />,则该语句必须返回两个java.sql.ResultSet  (即一个用于userWiseData,另一个用于关联)。
resultSetsresultSet通常与存储过程一起使用。请参阅example in the documentation
如果确实如此,则应更新您的问题,以包括有关存储过程的信息。

假设您的目标是在映射复杂结果时重用结果映射,columnPrefix会派上用场。
在为您分配了适当的列别名后,我可以使用以下结果图获得预期的结果。

<resultMap type="test.UserWiseData" id="UserWiseDataRM"
  autoMapping="false">
  <id property="personId" column="person_id" />
  <association property="mandatorySTC" resultMap="TypeWiseDataRM" />
</resultMap>

<resultMap type="test.TypeWiseData" id="TypeWiseDataRM">
  <id property="typeId" column="type_id" />
  <result property="personId" column="person_id" />
  <collection property="hrCompanyWiseData"
    resultMap="HRCompanyWiseDataRM" />
</resultMap>

<resultMap type="test.HRCompanyWiseData"
  id="HRCompanyWiseDataRM">
  <id property="companyId" column="company_id" />
  <result property="companyCode" column="company_code" />
  <association property="nonMidYear"
    resultMap="PeriodWiseDataRM" columnPrefix="non_mid_year_" />
  <association property="midYear"
    resultMap="PeriodWiseDataRM" columnPrefix="mid_year_" />
</resultMap>

<resultMap type="test.PeriodWiseData" id="PeriodWiseDataRM">
  <id property="periodId" column="period_id" />
  <collection property="investmentDateWiseData"
    resultMap="InvestmentDateWiseDataRM" />
</resultMap>

<resultMap type="test.InvestmentDateWiseData"
  id="InvestmentDateWiseDataRM">
  <id property="investmentDateId" column="investment_date_id" />
  <collection property="vestingDateWiseData" 
    resultMap="VestingDateWiseDataRM" />
</resultMap>

<resultMap type="test.VestingDateWiseData"
  id="VestingDateWiseDataRM">
  <id property="vestingDateId" column="vesting_date_id" />
  <result property="awardDate" column="award_date" />
  <result property="investmentDate" column="investment_date" />
  <result property="vestingDate" column="vesting_date" />
  <result property="amount" column="amount" />
  <result property="returnAmount" column="return_amount" />
  <result property="vestingAmount" column="vesting_amount" />
</resultMap>

这是我用来测试的portable demo (MCVE)

如果您向根结果图中添加更多<association />,则在较高结果图中可能需要columnPrefix,但是想法是相同的。

希望这会有所帮助!

答案 1 :(得分:0)

在SQL仅返回一个resultSet的情况下,请勿使用resultSets,它用于区分多个结果集。