带有连接结果列表的 JDBI 结果集映射?
JDBI resultset mapping with joined list of results?
尝试使用 JDBI ResultSetMapper 构建国家/地区对象 API,但是我遇到了一个问题,我不确定如何解决。
对于如下所示的结果集,将地区(州/地区)table 连接到国家 (1 - 0..n)
@Override
public Country map(final int index, final ResultSet resultRow, final StatementContext ctx) throws SQLException {
final String countryIso3Code = resultRow.getString("iso3Code");
return Country.builder().name(resultRow.getString("name"))
.iso2Code(resultRow.getString("iso2Code"))
.iso3Code(resultRow.getString("iso3Code"))
.regions(....?)
.build();
}
如何让 ResultSetMapper 使用 JDBI 中相关区域的适当列表初始化一个 Country 对象
例如
United States - (USA) - (US) - (PR, RI, WA)
目前返回的国家列表如下
United Kingdom - GBR - GB - <>
United States - USA - US - PR
United States - USA - US - RI
United States - USA - US - WA
Puerto Rico - PRI - PR - <>
Canada - CAN - CA - AB
Canada - CAN - CA - BC
您可以为此使用 StatementContext 参数。
当 map 方法看到一个新的国家时,它会创建一个新的国家实例并调用 ctx.setAttribute 来保存新实例。稍后,如果存在非空区域,它会将区域添加到从语句上下文中获取的 Country 实例。
这是一个例子:
@Override
public Country map(final int index, final ResultSet resultRow, final StatementContext ctx) throws SQLException {
final String countryIso3Code = resultRow.getString("iso3Code");
if (countryIso3Code == null) {
throw new SQLDataException("Iso3Code is required");
}
Country country = (Country)ctx.getAttribute(countryIso3Code);
if (country == null) {
country = new Country();
country.setName(resultRow.getString("name"));
country.setIso3Code(countryIso3Code);
country.setIso2Code(resultRow.getString("iso2Code"));
ctx.setAttribute(countryIso3Code, country);
}
String region = resultRow.getString("region");
if (region != null) {
country.addRegion(region);
}
return country;
}
像您在发布的代码中那样使用构建器有点不方便,但是可以将构建器放在语句上下文中而不是国家/地区。
另外,这个映射器 returns 每个数据库行一个国家,所以有七个结果,但是由于重复相同的实例,使用 Set 可以获得预期的四个结果。
Jdbi 提供了“减少行”功能来处理“合并结果”:https://jdbi.org/#_joins
您将需要实现一个 RowReducer,具有以下职责:
- 在第一次遇到国家时从结果集行构建国家(您可以使用简化的 RawMapper 实现)。检测可能基于国家/地区主键
- 将构建国家/地区存储在容器中,由其主键映射,以便在后续结果集行中再次遇到时能够检索它
- 如果当前行是关于一个已经遇到的国家,则从容器中检索国家,将当前行指定的区域添加到检索到的国家
Jdbi 使用行缩减器来解析每个结果集的行,并作为结果提供容器的内容。
你可以按照jdbi文档中的例子:https://jdbi.org/#_resultbearing_reducerows
尝试使用 JDBI ResultSetMapper 构建国家/地区对象 API,但是我遇到了一个问题,我不确定如何解决。
对于如下所示的结果集,将地区(州/地区)table 连接到国家 (1 - 0..n)
@Override
public Country map(final int index, final ResultSet resultRow, final StatementContext ctx) throws SQLException {
final String countryIso3Code = resultRow.getString("iso3Code");
return Country.builder().name(resultRow.getString("name"))
.iso2Code(resultRow.getString("iso2Code"))
.iso3Code(resultRow.getString("iso3Code"))
.regions(....?)
.build();
}
如何让 ResultSetMapper 使用 JDBI 中相关区域的适当列表初始化一个 Country 对象
例如
United States - (USA) - (US) - (PR, RI, WA)
目前返回的国家列表如下
United Kingdom - GBR - GB - <>
United States - USA - US - PR
United States - USA - US - RI
United States - USA - US - WA
Puerto Rico - PRI - PR - <>
Canada - CAN - CA - AB
Canada - CAN - CA - BC
您可以为此使用 StatementContext 参数。
当 map 方法看到一个新的国家时,它会创建一个新的国家实例并调用 ctx.setAttribute 来保存新实例。稍后,如果存在非空区域,它会将区域添加到从语句上下文中获取的 Country 实例。
这是一个例子:
@Override
public Country map(final int index, final ResultSet resultRow, final StatementContext ctx) throws SQLException {
final String countryIso3Code = resultRow.getString("iso3Code");
if (countryIso3Code == null) {
throw new SQLDataException("Iso3Code is required");
}
Country country = (Country)ctx.getAttribute(countryIso3Code);
if (country == null) {
country = new Country();
country.setName(resultRow.getString("name"));
country.setIso3Code(countryIso3Code);
country.setIso2Code(resultRow.getString("iso2Code"));
ctx.setAttribute(countryIso3Code, country);
}
String region = resultRow.getString("region");
if (region != null) {
country.addRegion(region);
}
return country;
}
像您在发布的代码中那样使用构建器有点不方便,但是可以将构建器放在语句上下文中而不是国家/地区。
另外,这个映射器 returns 每个数据库行一个国家,所以有七个结果,但是由于重复相同的实例,使用 Set
Jdbi 提供了“减少行”功能来处理“合并结果”:https://jdbi.org/#_joins
您将需要实现一个 RowReducer,具有以下职责:
- 在第一次遇到国家时从结果集行构建国家(您可以使用简化的 RawMapper 实现)。检测可能基于国家/地区主键
- 将构建国家/地区存储在容器中,由其主键映射,以便在后续结果集行中再次遇到时能够检索它
- 如果当前行是关于一个已经遇到的国家,则从容器中检索国家,将当前行指定的区域添加到检索到的国家
Jdbi 使用行缩减器来解析每个结果集的行,并作为结果提供容器的内容。
你可以按照jdbi文档中的例子:https://jdbi.org/#_resultbearing_reducerows