2017-03-06 93 views
1

嘗試使用JDBI的ResultSetMapper API構建Country對象,但是我有一個問題,我不知道如何解決。帶連接的結果列表的JDBI結果集映射?

對於像連接本地區(國家/地區)表國家以下一個結果(1 - 0到n)

enter image description here

@Override 
public Country map(final int index, final ResultSet resultRow, final StatementContext ctx) throws SQLException { 

    final String countryIso3Code = resultRow.getString("iso3Code"); 


    return Country.builder().name(resultRow.getString("name")) 
      .iso2Code(resultRow.getString("iso2Code")) 
      .iso3Code(resultRow.getString("iso3Code")) 
      .regions(....?) 
      .build(); 

} 

我怎樣才能得到ResultSetMapper初始化一個國家對象與JDBI中相關區域的適當清單

eg

美國 - (美國) - (美國) - (PR,RI,WA)

目前國家列表中返回的是像followng

英國 - GBR - GB - <>

美國 - 美國 - 美國 - PR

美國 - 美國 - 美國 - RI

美國 - 美國 - 美國 - WA

波多黎各 - PRI - PR - <>

加拿大 - CAN - CA - AB

加拿大 - CAN - CA - 公元前

回答

2

您可以使用StatementContext參數。

當map方法看到一個新的國家時,它會創建一個新的Country實例並調用ctx.setAttribute來保存新實例。稍後,如果存在非空區域,則會將該區域添加到從語句上下文中獲取的Country實例。

下面是一個例子:

@Override 
    public Country map(final int index, final ResultSet resultRow, final StatementContext ctx) throws SQLException { 

     final String countryIso3Code = resultRow.getString("iso3Code"); 
     if (countryIso3Code == null) { 
      throw new SQLDataException("Iso3Code is required"); 
     } 
     Country country = (Country)ctx.getAttribute(countryIso3Code); 
     if (country == null) { 
      country = new Country(); 
      country.setName(resultRow.getString("name")); 
      country.setIso3Code(countryIso3Code); 
      country.setIso2Code(resultRow.getString("iso2Code")); 
      ctx.setAttribute(countryIso3Code, country); 
     } 

     String region = resultRow.getString("region"); 
     if (region != null) { 
      country.addRegion(region); 
     } 
     return country; 
    } 

這是一個有點不方便就像你在你發佈的代碼做使用的建設者,但它可能把一個建設者的聲明範圍內,而不是一個國家。

此外,此映射程序返回一個國家每個數據庫行,所以七個結果,但由於重複相同的實例,使用集<國家>得到您預期的四個結果。