如何使用JDBI注解将聚合查询结果选择到元组中?

问题描述 投票:0回答:3

我正在使用 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();
java tuples jdbi
3个回答
2
投票

另一个答案是一个非常好的答案,但我只是想发布一个回答某人想知道的具体问题。

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


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
投票
现在您可以仅使用内置的

org.skife.jdbi.v2.DefaultMapper

 (至少在 v2.78+ 中),然后在客户端从 obj 转换为 int 类型,例如:

@SqlQuery("select count(*) as customerCount, location from Customers group by location") @Mapper(DefaultMapper.class) public List<Map<String, Object>> getCustomersCountByLocation(); ... int count = Integer.valueOf(dbRes.get(0).get("customerCount"))
    
© www.soinside.com 2019 - 2024. All rights reserved.