Вложенные и в MyBatis дают NULL в качестве результата

#java #mybatis #spring-mybatis

#java #мой батис #spring-mybatis #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                                    

  

Я пробовал это с column и foreignColumn с <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 из запроса, я получаю данные, как ожидалось.

Ответ №1:

Я думаю, вы неправильно понимаете значение resultSet .
Это означает java.sql.ResultSet , что, если вы укажете resultSet="mandatorySTCResult" в <association /> , из инструкции должно быть два java.sql.ResultSet s, возвращаемых (т. Е. один для userWiseData , а другой для ассоциации).
resultSets и resultSet обычно используется с хранимой процедурой. Пожалуйста, смотрите пример в документации.
Если это действительно так, вам следует обновить свой вопрос, чтобы включить информацию о хранимой процедуре.

Предполагая, что ваша цель — повторно использовать результирующие карты при отображении сложного результата, 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>
  

Вот портативная демонстрация (MCVE), которую я использовал для тестирования.

Если вы добавите больше <association /> к корневой результирующей карте, вам может понадобиться columnPrefix более высокие результирующие карты, но идея та же.

Надеюсь, это поможет!

Ответ №2:

Вы не должны использовать resultSets там, где ваш sql возвращает только один результирующий набор.Он используется для различения нескольких наборов результатов.

Комментарии:

1. Как я упоминал в своей правке, я должен вернуть несколько resultSets . Несмотря на то, что прямо сейчас я показываю только один, resultSet/resultMap мое намерение состоит в том, чтобы добавить 3-4 <associate> , каждый из которых имеет свой собственный результат. Причина, по которой я пытаюсь это сделать, заключается в том, что у меня создано много #temp таблиц, и я хочу их повторно использовать. Я не смогу этого сделать, если буду писать отдельно resultMaps для каждого запроса.