如何使用JDBI注释将聚合查询结果选择为元组?

时间:2016-02-05 09:32:47

标签: java tuples 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();

2 个答案:

答案 0 :(得分:1)

您可以使用地图代替。您需要编写一次mapper,它可以用于所有聚合查询,也可以用于其他用例。

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

并像这样定义mapper。

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;
    }
}

答案 1 :(得分: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();

然后在mapper类中:

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只能与几行代码一起使用。