gpt4 book ai didi

postgresql - 使用 MyBatis 将 PostgreSQL 聚合返回到 HashMap

转载 作者:行者123 更新时间:2023-11-29 13:50:37 36 4
gpt4 key购买 nike

我有一个 super 简单的表test例如

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

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

要获得聚合计数,我可以运行:-

1) 使用 group by 的简单多行结果

select status, 
count(id) as count
from test
group by status

...返回...

-------+-------
status | counts
-------+-------
go | 3
ready | 2
new | 1
steady | 1
-------+-------

2) 使用 jsonb_object_agg 的单行结果

    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接口(interface)方法。

在我的 Java 代码中(通过 MyBatis)我有一个方法:-

public Map<String, Integer> selectStatusCounts();

我很想知道如何将任一查询映射到 Map<String, Integer>通过 MyBatis 的 Java 对象?


更新(一)

关于 a_horse_with_no_name建议和this stackover article我想出了这个:-

3) 使用 hstore 的单行结果

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

马上测试! :-)


更新(二)

谢谢 a_horse_with_no_name再次感谢您的贡献 - 我现在非常接近,但仍然对 MyBatis 感到奇怪。这是我创建的类型处理程序(因此我可以在其他地方重用聚合):-

@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();

}

... 这是 <select>在 XML 映射器文件中 ...

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

但是,它返回一个 Map有一个名为 status_counts 的条目其值是我想要的实际 map ,即 {status_counts={new=1, ready=2, go=3, steady=1}}

以下是我对 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/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com