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

k5ifujac  于 2024-01-05  发布在  Java
关注(0)|答案(3)|浏览(186)

我正在使用JDBI,我需要使用聚合函数运行查询。
我该如何阅读这个查询的结果?我可以使用什么返回类型来方便它?

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

字符串
我可能会向聚合函数结果添加一个别名,并编写一个匹配的POJO

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


POJO是:

  1. public class CustomerLocation {
  2. private int customerCount;
  3. private String location;
  4. public CustomerLocation(int customerCount, String location) {
  5. this.customerCount = customerCount;
  6. this.location = location;
  7. }
  8. //getters
  9. }


我可以为这类查询编写一个通用的对象,但这会引入不必要的耦合。
JDBI是否支持任何类型的OOTB,允许我将查询的结果选择到一个用正确类型参数化的任意n元组中?
伪代码:

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

yyhrrdl8

yyhrrdl81#

other answer是一个非常好的,但我只是想发布一个回答具体问题是有人想知道。
Manikandan的建议可以用org.apache.commons.lang3.tuple.Pair来完成。

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

字符串
然后在mapper类中:

  1. public class CustomerCountByLocationMapper implements ResultSetMapper<Pair<String, Integer>> {
  2. @Override
  3. public Pair<String, Integer> map(int index, ResultSet r, StatementContext ctx) throws SQLException {
  4. String location = r.getString("location");
  5. Integer customerCount = r.getInt("customerCount");
  6. return Pair.of(source, count);
  7. }
  8. }


在这种情况下,getCustomersCountByLocation方法将返回一个List<Pair<String,Integer>>,正如另一个答案所指出的,这是一个愚蠢的类型,具有这种语义的对列表实际上是一个Map。
同时,ResultSetMapper接口足够灵活,允许Map到完全任意的类型。在一个更合适的上下文中,Pair只需要几行代码就可以使用。

展开查看全部
wsewodh2

wsewodh22#

你可以使用Map代替。你只需要写一次mapper,它可以用于所有聚合查询,也可以用于其他用例。

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

字符串
并像这样定义mapper。

  1. public class MapMapper implements ResultSetMapper<Map<String, Integer>> {
  2. @Override
  3. public Map<String, Integer> map(int index, ResultSet r, StatementContext ctx) throws SQLException {
  4. HashMap<String, Integer> result = new HashMap<>();
  5. for(int i =1; i <= r.getMetaData().getColumnCount(); i++) {
  6. String columnName = r.getMetaData().getColumnName(i);
  7. Integer value = r.getInt(i);
  8. result.put(columnName, value);
  9. }
  10. return result;
  11. }
  12. }

展开查看全部
yebdmbv4

yebdmbv43#

现在,正如我发现的,我们可以使用内置的org.skife.jdbi.v2.DefaultMapper(至少在v2.78+中),然后在客户端将obj转换为int,例如:

  1. @SqlQuery("select count(*) as customerCount, location from Customers group by location")
  2. @Mapper(DefaultMapper.class)
  3. public List<Map<String, Object>> getCustomersCountByLocation();
  4. ...
  5. int count = Integer.valueOf(dbRes.get(0).get("customerCount"))

字符串

相关问题