我有一张超级简单的桌子。

create table test (
    id serial primary key,
    status varchar (10)
);

insert into test (status)
     values ('ready'), ('ready'),
            ('steady'),
            ('go'), ('go'), ('go'),
            ('new');

要获取可以运行的聚合计数:-
1)使用test的简单多行结果
select status,
       count(id) as count
  from test
 group by status

... 又回来了。。。
-------+-------
status | counts
-------+-------
go     |      3
ready  |      2
new    |      1
steady |      1
-------+-------

2)使用group by的单行结果
    with stats as (
       select status,
              count(id) as count
         from test
     group by status
    )
    select jsonb_object_agg (status, count) as status_counts from stats

... 又回来了。。。
--------------------------------------------------
status_counts
--------------------------------------------------
{ "go" : 3, "new" : 1, "ready" : 2, "steady" : 1 }
--------------------------------------------------

Mybatis接口方法。
在我的Java代码中(通过MyBatis),我有一个方法:-
public Map<String, Integer> selectStatusCounts();

我想知道的是如何通过MyBatis将查询映射到Java对象?
更新(1)
关于jsonb_object_agg的建议和this stackover article我想到了这个:-
3)使用Map<String, Integer>的单行结果
select hstore(array_agg(hs_key), array_agg(hs_value::text))
from (
    select
        status,
        count(id) as count
    from test
    group by status
) x(hs_key,hs_value)

... 又回来了。。。
--------------------------------------------------
status_counts
--------------------------------------------------
"go"=>"3", "new"=>"1", "ready"=>"2", "steady"=>"1"
--------------------------------------------------

使用这样的方法可能会奏效:-
https://github.com/gbif/checklistbank/blob/master/checklistbank-mybatis-service/src/main/java/org/gbif/checklistbank/service/mybatis/postgres/HstoreCountTypeHandler.java
现在就要测试了!:-)
更新(2)
再次感谢你的贡献-我现在很接近,但对我的巴蒂斯还是很奇怪。下面是我创建的类型处理程序(以便在其他地方重用聚合):-
@MappedTypes(LinkedHashMap.class)
@MappedJdbcTypes(JdbcType.OTHER)
public class MyBatisMapHstoreToStringIntegerMap implements TypeHandler<Map<String, Integer>> {

    public MyBatisMapHstoreToStringIntegerMap() {}

    public void setParameter(PreparedStatement ps, int i, Map<String, Integer> map, JdbcType jdbcType) throws SQLException {
        ps.setString(i, HStoreConverter.toString(map));
    }

    public Map<String, Integer> getResult(ResultSet rs, String columnName) throws SQLException {
        return readMap(rs.getString(columnName));
    }

    public Map<String, Integer> getResult(ResultSet rs, int columnIndex) throws SQLException {
        return readMap(rs.getString(columnIndex));
    }

    public Map<String, Integer> getResult(CallableStatement cs, int columnIndex) throws SQLException {
        return readMap(cs.getString(columnIndex));
    }

    private Map<String, Integer> readMap(String hstring) throws SQLException {
        if (hstring != null) {
            Map<String, Integer> map = new LinkedHashMap<String, Integer>();
            Map<String, String> rawMap = HStoreConverter.fromString(hstring);
            for (Map.Entry<String, String> entry : rawMap.entrySet()) {
                map.put(entry.getKey(), Integer.parseInt(entry.getValue())); // convert from <String, String> to <String,Integer>
            }

            return map;
        }
        return null;
    }

}

... 这是映射器接口。。。
public interface TestMapper {

    public Map<String, Integer> selectStatusCounts();

}

... 这里是XML映射器文件中的a_horse_with_no_name。。。
<select id="selectStatusCounts" resultType="java.util.LinkedHashMap">
    select hstore(array_agg(hs_key), array_agg(hs_value::text)) as status_counts
    from (
        select
            status,
            count(id) as count
        from test
        group by status
    ) x(hs_key,hs_value)
</select>

但是,它返回一个名为hstorea_horse_with_no_name条目,其值是我想要的实际映射,即<select>
以下是我对PostgreSQL/MyBatis的maven依赖关系:-
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.2.2</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.3.1</version>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.4-1201-jdbc41</version>
    </dependency>

最佳答案

最简单的方法是定义一个hstore_agg()函数:

CREATE AGGREGATE hstore_agg(hstore)
(
    SFUNC = hs_concat(hstore, hstore),
    STYPE = hstore
);

然后你可以这样做:
select hstore_agg(hstore(status, cnt::text))
from (
  select status, count(*) cnt
  from test
  group by status
) t;

使用当前的JDBC驱动程序Statement.getObject()将返回Map<String, String>
因为hstore只存储字符串,所以它不能返回Map<String, Integer>

关于postgresql - 使用MyBatis将PostgreSQL聚合返回到HashMap,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41762787/

10-13 04:16