Использовать BeanMapper из RowMapper? - PullRequest
0 голосов
/ 20 января 2020

Я использую декларативный API SQL Objects JDBI для сопоставления объекта, содержащего отношение один-ко-многим:

class Foo {
  private String id;
  private String name;
  private Set<Bar> bars = new HashSet<>();
}

class Bar {
  private String id;
}

Изначально это выглядело как RowReducer, было бы идеально:

@UseFreemarkerSqlLocator
class FooQuery {

  @SqlQuery
  @RegisterBeanMapper(value = Foo.class, prefix = "f")
  @RegisterBeanMapper(value = Bar.class, prefix = "b")
  @UseRowReducer(RowReducer.class)
  ResultIterator<Foo> queryAll();

  static class RowReducer implements LinkedHashMapRowReducer<String, Foo> {

    @Override
    public void accumulate(Map<String, Foo> map, RowView rowView) {
      final Foo foo = map.computeIfAbsent(rowView.getColumn("f_id", String.class),
          id -> rowView.getRow(Foo.class));
      if (rowView.getColumn("b_id", String.class) != null) {
        foo.addBar(rowView.getRow(Bar.class));
      }
    }
  }
}

Однако вскоре я обнаружил, что RowReducer s не работают с ResultIterator s (я работаю с большой базой данных, поэтому важно иметь возможность передавать их в потоковом режиме), так что теперь я возвращаюсь вернуться к реализации RowMapper вместо. Я все еще хотел бы использовать удобные BeanMapper, встроенные в JDBI, но я не могу понять, как получить к ним доступ из моей реализации RowMapper.

class FooRowMapper implements RowMapper<Foo> {
  private Foo foo = null;

  @Override
  public Foo map(ResultSet rs, StatementContext ctx) throws SQLException {
    String fooId = rs.getString("f_id");
    if (foo == null || !foo.id.equals(fooId)) {
      // ideally construct using JDBI's BeanMapper similar to how we can above
      // in the RowReducer!
      foo = ??? 
    }
    // same as above...
    Bar bar = ???
    foo.addBar(bar);

    return foo;
  }
}

Возможно ли легко использовать BeanMappers из RowMapper, поэтому мне не нужно вручную создавать bean-компоненты?

...