Динамический собственный запрос с одним или несколькими столбцами и отображением результатов (Object vs Object []) - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть несколько очень простых SQL, где в основном меняются столбцы и таблица, например, просто:

Select :COLUMNS from :TABLE

SQL может иметь 1 или несколько столбцов, и всегда есть 1 таблица,Я использовал JPA только потому, что мы находимся на сервере Java EE 7.Таким образом, код для выполнения собственных запросов выглядит следующим образом:

@PersistenceContext(unitName = "sample")
EntityManager entityManager;
public List<Result> getResults() {
  return Stream.of("SELECT one FROM demo1",
                   "SELECT two, columns FROM demo2")
               .map(entityManager::createNativeQuery)
               .map(Query::getSingleResult)
               .flatMap(result -> {
                  // is Object for the first...
                  // and Object[] for the second...
                  if (result instanceof Object[]) {
                    return Arrays.stream((Object[])result);
                  } else {
                    return Stream.of(result);
                  }
               })
               .map(Result::new)
               .collect(Collectors.toList());
}

Проблема, с которой я столкнулся сейчас: если я использую только один столбец, я получаю Object напрямую, а если я использую несколько столбцов, я получаюObject[].Есть ли свойство / параметр, чтобы всегда получать Object[]?Я видел, что setHint(ResultType, Array) может решить эту проблему, но для этого нужны советы, специфичные для реализации.

Причина, по которой я в первую очередь хочу Object[]: (кроме того, что код уже уродлив в этом конкретном instanceof) сам результат полезен, только если я все еще знаю соответствующий столбец для него.Пример кода довольно упрощает это, но поскольку SQL создается динамически, столбцы также известны и поэтому могут быть использованы повторно.Если есть какое-то другое отображение набора результатов, которое можно было бы использовать для такой конструкции, я все уши.

Пока я просто использую показанную проверку instanceof, но я задавался вопросом, есть ли что-то в стандартеэто, возможно, уже решает эту проблему.Любые советы о том, как лучше решить эту проблему, приветствуются (без дальнейшей зависимости, конечно).

Примечание: я не могу адаптировать таблицы, и результат действительно имеет смысл таким образом.

1 Ответ

0 голосов
/ 24 сентября 2018

Вы можете пропустить весь тест instanceof и воспользоваться преимуществами полиморфной сигнатуры метода Stream.of (), который принимает один объект или массив объектов:

static <T> Stream<T> of(T... values).
static <T> Stream<T> of(T t)

, чтосделайте ваш код более читабельным:

public List<Result> getResults() {
  return Stream.of("SELECT...", "SELECT...")
               .map(entityManager::createNativeQuery)
               .map(Query::getSingleResult)
               .flatMap(result -> Stream.of(result) )
               .map(Result::new)
               .collect(Collectors.toList());
}
...