2016-02-05 65 views
0

我正在使用JDBI,我需要使用聚合函數來運行查詢。如何使用JDBI註釋將聚合查詢結果選擇爲元組?

我該如何去閱讀這個查詢的結果?我可以使用哪種返回類型以方便使用?

@SqlQuery("select count(*), location from Customers group by location") 
public Type getCustomersCountByLocation(); 

我一個別名可能添加到聚合函數的結果,寫一個匹配POJO

@SqlQuery("select count(*) as customerCount, location from Customers group by location") 
public List<CustomerLocation> getCustomersCountByLocation(); 

的POJO之中:

public class CustomerLocation { 

    private int customerCount; 

    private String location; 

    public CustomerLocation(int customerCount, String location) { 
     this.customerCount = customerCount; 
     this.location = location; 
    } 

    //getters 
} 

但是,這似乎是一個很多不必要的樣板。我可以爲這種查詢編寫一個適合所有情況的對象,但這會引入不必要的耦合。

JDBI支持任何類型的OOTB,它允許我選擇我的查詢結果爲任意正確類型的參數化n元組嗎?

僞代碼:

@SqlQuery("select count(*) as customerCount, location from Customers group by location") 
public List<Tuple<Integer, String>> getCustomersCountByLocation(); 

回答

1

你可以使用地圖來代替。您需要編寫一次映射器,它可以用於所有聚合查詢,也可以用於其他用例。

@SqlQuery("select count(*) as customerCount, location from Customers group by location") 
@Mapper(MapMapper.class) 
public Map getCustomersCountByLocation(); 

並定義這樣的映射器。

public class MapMapper implements ResultSetMapper<Map<String, Integer>> { 
    @Override 
    public Map<String, Integer> map(int index, ResultSet r, StatementContext ctx) throws SQLException { 
     HashMap<String, Integer> result = new HashMap<>(); 
     for(int i =1; i <= r.getMetaData().getColumnCount(); i++) { 
      String columnName = r.getMetaData().getColumnName(i); 
      Integer value = r.getInt(i); 
      result.put(columnName, value); 
     } 
     return result; 
    } 
} 
+0

好的建議,地圖可能更容易解釋。我完全忘記了這些映射器的存在,儘管我已經有了一個POJO。也沒有意識到我可以分配一個映射到一個特定的查詢。 – toniedzwiedz

+0

謝謝。你可以在多個層次上分配映射器。方法級別具有較高的優先級,然後是級別級別,然後是應用級別映射器。 – Manikandan

1

other answer是一個很好的人,但我只是想發佈一個回答的具體問題是誰家的疑惑。

Manikandan提出的建議可以用org.apache.commons.lang3.tuple.Pair完成。

@SqlQuery("select count(*) as customerCount, location from Customers group by location") 
@Mapper(CustomerCountByLocationMapper.class) 
public List<Pair<String, Integer>> getCustomersCountByLocation(); 

然後在映射類:

public class CustomerCountByLocationMapper implements ResultSetMapper<Pair<String, Integer>> { 

    @Override 
    public Pair<String, Integer> map(int index, ResultSet r, StatementContext ctx) throws SQLException { 
     String location = r.getString("location"); 
     Integer customerCount = r.getInt("customerCount"); 
     return Pair.of(source, count); 
    } 
} 

在這種情況下,getCustomersCountByLocation方法將返回一個List<Pair<String,Integer>>,其中,由對方的回答中指出,是一個愚蠢的類型和列表與這種語義配對實際上是一張地圖。

與此同時,ResultSetMapper接口足夠靈活,可以映射到完全任意類型。在更合適的情況下,Pair只需幾行代碼即可使用。

相關問題